<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\worker;

require_once  __DIR__.'/mysql-master/src/Connection.php';

class DataService{

    static $gabyCRCHi = [
        0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0, 0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41, 0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0, 0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40, 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x00,0xc1, 0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41, 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x00,0xc1, 0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41, 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0, 0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40, 0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1, 0x81,0x40,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40, 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0, 0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40, 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0, 0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40, 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0, 0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41, 0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0, 0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41, 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0, 0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40, 0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1, 0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0, 0x80,0x41,0x00,0xc1,0x81,0x40
    ];

    static $gabyCRCLo=[
        0x00,0xc0,0xc1,0x01,0xc3,0x03,0x02,0xc2,0xc6,0x06, 0x07,0xc7,0x05,0xc5,0xc4,0x04,0xcc,0x0c,0x0d,0xcd, 0x0f,0xcf,0xce,0x0e,0x0a,0xca,0xcb,0x0b,0xc9,0x09, 0x08,0xc8,0xd8,0x18,0x19,0xd9,0x1b,0xdb,0xda,0x1a, 0x1e,0xde,0xdf,0x1f,0xdd,0x1d,0x1c,0xdc,0x14,0xd4, 0xd5,0x15,0xd7,0x17,0x16,0xd6,0xd2,0x12,0x13,0xd3, 0x11,0xd1,0xd0,0x10,0xf0,0x30,0x31,0xf1,0x33,0xf3, 0xf2,0x32,0x36,0xf6,0xf7,0x37,0xf5,0x35,0x34,0xf4, 0x3c,0xfc,0xfd,0x3d,0xff,0x3f,0x3e,0xfe,0xfa,0x3a, 0x3b,0xfb,0x39,0xf9,0xf8,0x38,0x28,0xe8,0xe9,0x29, 0xeb,0x2b,0x2a,0xea,0xee,0x2e,0x2f,0xef,0x2d,0xed, 0xec,0x2c,0xe4,0x24,0x25,0xe5,0x27,0xe7,0xe6,0x26, 0x22,0xe2,0xe3,0x23,0xe1,0x21,0x20,0xe0,0xa0,0x60, 0x61,0xa1,0x63,0xa3,0xa2,0x62,0x66,0xa6,0xa7,0x67, 0xa5,0x65,0x64,0xa4,0x6c,0xac,0xad,0x6d,0xaf,0x6f, 0x6e,0xae,0xaa,0x6a,0x6b,0xab,0x69,0xa9,0xa8,0x68, 0x78,0xb8,0xb9,0x79,0xbb,0x7b,0x7a,0xba,0xbe,0x7e, 0x7f,0xbf,0x7d,0xbd,0xbc,0x7c,0xb4,0x74,0x75,0xb5, 0x77,0xb7,0xb6,0x76,0x72,0xb2,0xb3,0x73,0xb1,0x71, 0x70,0xb0,0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92, 0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9c,0x5c, 0x5d,0x9d,0x5f,0x9f,0x9e,0x5e,0x5a,0x9a,0x9b,0x5b, 0x99,0x59,0x58,0x98,0x88,0x48,0x49,0x89,0x4b,0x8b, 0x8a,0x4a,0x4e,0x8e,0x8f,0x4f,0x8d,0x4d,0x4c,0x8c, 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42, 0x43,0x83,0x41,0x81,0x80,0x40
    ];


    /**
     * 帧校验域
     * @param $str
     * @param int $len
     * @return string
     */
    function modBusCRC($str, $len = 0)
    {
        $str = strtoupper($str);
        $pData = pack('H*',$str);     //高位在前
        $len = ($len <= 0 ? strlen($pData) : $len);
        $byCRCHi = 0xff;
        $byCRCLo = 0xff;
        $byIdx = 0;
        for ($i = 0; $i < $len; $i++) {
            $byIdx = $byCRCHi ^ ord(substr($pData, $i, 1));
            $byCRCHi = $byCRCLo ^ self::$gabyCRCHi[$byIdx];
            $byCRCLo = self::$gabyCRCLo[$byIdx];
        }
        $setData = chr($byCRCLo) . chr($byCRCHi);
        return unpack("H*",$setData)[1];
    }

    /**
     * src16的另外一种计算方法
     * @param $str
     * @param int $length
     * @return string
     */
    function src16($str,$length=0){
        $string = pack('H*',$str);     //高位在前
        $length        = ($length <= 0 ? strlen($string) : $length);
        $uchCRCHi    = 0xFF;
        $uchCRCLo    = 0xFF;
        $uIndex        = 0;
        for ($i = 0; $i < $length; $i++) {
            $uIndex        = $uchCRCLo ^ ord(substr($string, $i, 1));
            $uchCRCLo    = $uchCRCHi ^ self::$gabyCRCHi[$uIndex];
            $uchCRCHi    = self::$gabyCRCLo[$uIndex];
        }
        return chr($uchCRCLo) . chr($uchCRCHi);
    }


    /**
     * 记录上传上来的数据
     * @param $db
     * @param $client_id
     * @param $data
     * @param string $remark
     * @return mixed
     */
    function addMsgRecord($db,$client_id,$message,$remark=''){
        return $db->insert('jy_workerman_record')->cols([
            'client_id'=>$client_id,
            'content'=>$message,
            //'code_type'=>mb_detect_encoding($message,['CP936', "ASCII","GB2312","GBK",'UTF-8','BIG5']),
            'remark'=>$remark,
            'create_time'=>date("Y-m-d H:i:s"),
            'update_time'=>date("Y-m-d H:i:s")
        ])->query();
    }

    /**
     * 参数设置
     * @param $str
     * @param int $numberStatus
     * @return array
     */
    function setPostData($str,$numberStatus = 1){
        $startNumber = substr($str, 0, 2);
        if($startNumber != 68){
            return ['code'=>1,'msg'=>'数据错误'];
        }
        $status = true;
        $backData = ['code'=>0, 'msg'=>'数据设置成功','data'=>[]];
        while ($status){
            $dataLength = substr($str, 2, 2);
            $setData = [
                'start_number'=>substr($str, 0, 2),
                'data_length'=>$dataLength,
                'sor_number'=>substr($str, 4,4),
                'encryption'=>substr($str, 8,2),
                'use_status'=>substr($str, 10,2),
                //'data_info'=>substr($str, 12,-4),
                //'check_number'=>substr($str, -4),
                'data_info'=>substr($str, 12,(hexdec($dataLength)*2 - 8)),
                'check_number'=>substr($str, ((hexdec($dataLength) * 2) + 2 + 2),4),
                'check_data'=>substr($str, 12,(hexdec($dataLength)*2 - 8)),
                'content_len'=> hexdec($dataLength)*2,
                'get_content'=>substr($str, 0,((hexdec($dataLength) * 2) + 2 + 2 + 4)),
            ];
            if($setData['start_number'] == '68' && $setData['data_info']){
                $backData['data'][] = $setData;
            }
            //截取新的字符串
            $start = (hexdec($dataLength) * 2) + 2 + 2 + 4;
            $str = substr($str, $start);
            $checkStr = substr($str, 0, 2);
            if(strlen($str) <= 0 || $checkStr != '68'){
                $status = false;
                break;
            }
        }
        return $backData;
        /*
        $dataLength = substr($str, 2, 2);
        return $backData = [
            'code'=>0,
            'msg'=>'数据设置成功',
            'data'=>[
                'start_number'=>substr($str, 0, 2),
                'data_length'=>$dataLength,
                'sor_number'=>substr($str, 4,4),
                'encryption'=>substr($str, 8,2),
                'use_status'=>substr($str, 10,2),
                //'data_info'=>substr($str, 12,-4),
                'data_info'=>substr($str, 12,(hexdec($dataLength)*2 - 8)),
                'check_number'=>substr($str, -4),
                'check_data'=>substr($str, 12,(hexdec($dataLength)*2 - 8))
            ],
        ];
        */
    }

    /**
     * 设置返回对应数据结构
     * @param $sorNumber
     * @param $encryption
     * @param $useStatus
     * @param $data
     * @param $checkNumber
     * @return string
     */
    function setBackData($sorNumber,$encryption,$useStatus,$data){
        //$dataLength = (strlen($data)/2)+2+1+1;
        $dataLength = dechex((strlen($data)/2)+2+1+1);
        if(strlen($dataLength) < 2) $dataLength = '0'.$dataLength;
        $checkNumber = $this->modBusCRC($sorNumber.$encryption.$useStatus.$data);
        return $backData = '68'.$dataLength.$sorNumber.$encryption.$useStatus.$data.$checkNumber;
    }

    /**
     * 添加操作记录
     * @param $db
     * @param $pileInfo
     * @param $operationType
     * @param $inputData
     * @param $backData
     * @param $recordId
     * @param string $remark
     * @return mixed
     */
    function addOperationRecord($db,$pileInfo,$operationType,$inputData,$backData,$recordId,$remark=''){
        $outResult = 0;
        if(isset($backData['code']) && $backData['code'] > 0) $outResult = $backData['code'];
        return  $db->insert('jy_pile_operation_record')->cols([
            'pile_id'=>$pileInfo['id'],
            'station_id'=>$pileInfo['station_id'],
            'device_sn'=>$pileInfo['device_sn'],
            'operation_type'=>$operationType,
            'input_data'=>json_encode($inputData,JSON_UNESCAPED_UNICODE),
            'out_data'=>json_encode($backData,JSON_UNESCAPED_UNICODE),
            'out_result'=>$outResult,
            'record_id'=>$recordId,
            'remark'=>$remark,
            'create_time'=>date("Y-m-d H:i:s")
        ])->query();
    }

    /**
     * 充电桩登录
     * @param $db
     * @param $data
     * @param $recordId
     * @return array
     */
    function chargePileLogin($db,$data,$recordId=0,$client_id){
        $pileData = ['last_login_time'=>date("Y-m-d H:i:s"),'is_use'=>'3'];
        $pileNumber = substr($data['data_info'], 0,14);//获取设备编号
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$pileNumber."' && is_delete=1")->row();
        $modeInfo = $db->select('*')->from('jy_charge_pile_cost')->where("id=".$pileInfo['cost_id'])->row();
        if(!$pileInfo || !$modeInfo){
            $backData = ['code'=>1,'msg'=>'设备/计费模式不存在','back_data'=>$this->setBackData($data['sor_number'],$data['encryption'],'02',$pileNumber.'01')];
        }else if($pileInfo['is_status'] == 0){
            $backData = ['code'=>2,'msg'=>'设备未启用','back_data'=>$this->setBackData($data['sor_number'],$data['encryption'],'02',$pileNumber.'01')];
            $pileResult = $db->update('jy_charge_pile')->cols($pileData)->where('id='.$pileInfo['id'])->query();
        }else{
            $pileData['is_use'] = '1';
            $updateClientResult = $db->update('jy_pile_client')->where('pile_id='.$pileInfo['id'].' && is_delete=1')->cols(['is_delete'=>2,'update_time'=>date("Y-m-d H:i:s")])->query();
            $db->beginTrans();
            $pileResult = $db->update('jy_charge_pile')->where('id='.$pileInfo['id'])->cols($pileData)->query();
            $addClientResult = $db->insert('jy_pile_client')->cols([
                'pile_id'=>$pileInfo['id'],
                'client_id'=>$client_id,
                'is_delete'=>1,
                'create_time'=>date("Y-m-d H:i:s"),
                'update_time'=>date("Y-m-d H:i:s")
            ])->query();
            //记录client_id与设备的关系
            if($pileResult && $addClientResult){
                $db->commitTrans();
                $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'02',$pileNumber.'00');
                $backData = ['code'=>0,'msg'=>'设备登录成功','back_data'=>$backInfo];
            }else{
                $db->rollBackTrans();
                $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'02',$pileNumber.'01');
                $backData = ['code'=>3,'msg'=>'设备登录失败','back_data'=>$backInfo];
            }
        }
        if($pileInfo){
            $this->addOperationRecord($db,$pileInfo,1,$data,$backData,$recordId,$backData['msg']);
        }
        return $backData;
    }

    /**
     * 心跳包回应
     * @param $db
     * @param $data
     * @param int $recordId
     * @return array
     */
    function pileHeartBeat($db,$data,$recordId=0,$client_id){
        //获取设备状态
        $pileNumber = substr($data['data_info'], 0,14);//获取设备编号
        $pileGunNumber = substr($data['data_info'], 14,2);
        $pileStatus = substr($data['data_info'], 16,2);
        $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'04',$pileNumber.$pileGunNumber.$pileStatus);
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$pileNumber."' && is_delete=1")->row();

        if(!$pileInfo){
            $backData = ['code'=>1,'msg'=>'设备不存在','back_data'=>$backInfo];
        }else{
            //获取枪的记录
            $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id=".$pileInfo['id']." && num=".$pileGunNumber)->row();
            if(!$gunInfo){
                $gunId = $db->insert('jy_charge_pile_gun')->cols([
                    'pile_id'=>$pileInfo['id'],
                    'is_status'=>1,
                    'is_homing'=>1,
                    'remark'=>'',
                    'error_remark'=>'',
                    'num'=>$pileGunNumber,
                    'create_time'=>date("Y-m-d H:i:s"),
                    'update_time'=>date("Y-m-d H:i:s")
                ])->query();
            }else{
                $gunId = $gunInfo['id'];
            }
            //充电枪正常
            if($pileStatus == 00){
                //检查充电桩对应的clientId
                $clientInfo = $db->select('*')->from('jy_pile_client')->where("pile_id='".$pileInfo['id']."' && is_delete=1")->orderByDESC(['id'])->row();
                if(!$clientInfo){
                    $addClientResult = $db->insert('jy_pile_client')->cols([
                        'pile_id'=>$pileInfo['id'],
                        'client_id'=>$client_id,
                        'is_delete'=>1,
                        'create_time'=>date("Y-m-d H:i:s"),
                        'update_time'=>date("Y-m-d H:i:s")
                    ])->query();
                //存在不是对应的链接
                }else if($clientInfo['client_id'] != $client_id){
                    $updateClientResult = $db->update('jy_pile_client')->where('pile_id='.$pileInfo['id'].' && is_delete=1')->cols(['is_delete'=>2,'update_time'=>date("Y-m-d H:i:s")])->query();
                    if($updateClientResult){
                        $addClientResult = $db->insert('jy_pile_client')->cols([
                            'pile_id'=>$pileInfo['id'],
                            'client_id'=>$client_id,
                            'is_delete'=>1,
                            'create_time'=>date("Y-m-d H:i:s"),
                            'update_time'=>date("Y-m-d H:i:s")
                        ])->query();
                    }
                }
                //设置返回的数据
                $backData = ['code'=>0,'msg'=>'充电枪正常','back_data'=>$backInfo];
                if($gunInfo && $gunInfo['is_status'] == 2){
                    $updateData = ['is_status'=>1,'error_remark'=>$pileGunNumber.'充电枪运行正常','update_time'=>date("Y-m-d H:i:s")];
                    $gunResult = $db->update('jy_charge_pile_gun')->cols($updateData)->where('id='.$gunId)->query();
                    //$this->addOperationRecord($db,$pileInfo,2,$data,$backData,$recordId,$backData['msg']);
                }
            //充电枪异常
            }else{
                $backData = ['code'=>1,'msg'=>$pileGunNumber.'充电枪异常','back_data'=>$backInfo];
                if((!$gunInfo || $gunInfo['is_status'] == 1) && $gunId){
                    $updateData = ['is_status'=>2,'error_remark'=>$pileGunNumber.'充电枪异常','update_time'=>date("Y-m-d H:i:s")];
                    $gunResult = $db->update('jy_charge_pile_gun')->cols($updateData)->where('id='.$gunId)->query();
                    //$this->addOperationRecord($db,$pileInfo,2,$data,$backData,$recordId,$backData['msg']);
                }
            }
        }
        return $backData;
    }

    /**
     * 计费模式
     * @param $db
     * @param $data
     * @param int $recordId
     * @return array
     */
    function checkPileBillingMode($db,$data,$recordId=0){
        //获取设备状态
        $pileNumber = substr($data['data_info'], 0,14);//获取设备编号
        $modeNumber = substr($data['data_info'], 14,4);//计费模型
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$pileNumber."' && is_delete=1")->row();
        if(!$pileInfo){
            $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'06',$pileNumber.'000001');
            $backData = ['code'=>1,'msg'=>'设备不存在','back_data'=>$backInfo];
            return $backData;
        }else{
            $modeInfo = $db->select('*')->from('jy_charge_pile_cost')->where("id=".$pileInfo['cost_id'])->row();
            if(!$modeInfo){
                $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'06',$pileNumber.'000001');
                $backData = ['code'=>1,'msg'=>'收费模型不在','back_data'=>$backInfo];
                return $backData;
            }else{
                if($modeInfo['billing_mode'] != $modeNumber){
                    $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'06',$pileNumber.$modeInfo['billing_mode'].'01');
                    $backData = ['code'=>1,'msg'=>'收费模型不一致','back_data'=>$backInfo];
                    return $backData;
                }else{
                    $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'06',$pileNumber.$modeInfo['billing_mode'].'00');
                    $backData = ['code'=>0,'msg'=>'收费模型一致','back_data'=>$backInfo];
                    return $backData;
                }
            }
        }
    }

    /**
     * 充电桩计费模型请求
     * @param $db
     * @param $data
     * @param $insertId
     * @return array
     */
    function getPileBillingMode($db,$data,$recordId){
        //获取设备信息
        $pileNumber = substr($data['data_info'], 0,14);//获取设备编号
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$pileNumber."' && is_delete=1")->row();
        $modeInfo = $db->select('*')->from('jy_charge_pile_cost')->where("id=".$pileInfo['cost_id'])->row();
        $costList = $this->numberToBin($pileInfo['charge_cost']*100000,8);
        $costList = $costList.$this->numberToBin($pileInfo['service_cost']*100000,8);
        $costList = $costList.$this->numberToBin($pileInfo['service_cost']*100000,8);
        $costList = $costList.$this->numberToBin($pileInfo['peak_electric_cost']*100000,8);
        $costList = $costList.$this->numberToBin($pileInfo['peak_service_cost']*100000,8);
        $costList = $costList.$this->numberToBin($pileInfo['flat_electric_cost']*100000,8);
        $costList = $costList.$this->numberToBin($pileInfo['flat_service_cost']*100000,8);
        $costList = $costList.$this->numberToBin($pileInfo['valley_electric_cost']*100000,8);
        $costList = $costList.$this->numberToBin($pileInfo['valley_service_cost']*100000,8);
        if(!$modeInfo){
            //设置各个情况的费率
            $dataInfo = $pileNumber.$modeInfo['billing_mode'].$costList.'00';
            for($i=0;$i<48;$i++){
                $dataInfo = $dataInfo.'01';
            }
            $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'0A',$dataInfo);
            $backData = ['code'=>1,'msg'=>'收费模型不在','back_data'=>$backInfo];
        }else{
            //设置各个情况的费率
            $dataInfo = $pileNumber.$modeInfo['billing_mode'].$costList.'00';
            $i = 1;
            $getModelList = json_decode($modeInfo['cost_value'],true);
            $modelListData = [];
            foreach ($getModelList as $key=>$value){
                $modelListData[$value['name']] = $value['value'];
            }
            for($i=1;$i<=48;$i++){
                $dataInfo = isset($modelListData['model-'.$i]) ? $dataInfo.$modelListData['model-'.$i] : '01';
            }
            $backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'0A',$dataInfo);
            $backData = ['code'=>0,'msg'=>'返回收费模型成功','back_data'=>$backInfo];
        }
        $this->addOperationRecord($db,$pileInfo,3,$data,$backData,$recordId,$backData['msg']);
        return $backData;
    }

    /**
     * 上传实时监测数据
     * @param $db
     * @param $data
     * @param $recordId
     * @return array
     */
    function getChargePileData($db,$data,$recordId=0){
        $orderSn = substr($data['data_info'], 0,32);//获取订单编号
        $pileNumber = substr($data['data_info'], 32,14);//获取设备编号
        $pileGunNumber = substr($data['data_info'], 46,2);//获取设备枪号
        $pileStatus = substr($data['data_info'], 48,2);//获取设备状态 0x00：离线0x01：故障0x02：空闲0x03：充电,需做到变位上送
        $pileGunStatus = substr($data['data_info'], 50,2);//枪是否归位,0x00 否 0x01 是 0x02 未知
        $pileGunInsert = substr($data['data_info'], 52,2);//是否插枪,0x00 否 0x01 是 需做到变位上送
        $newStr = substr($data['data_info'], 54);//是否插枪,0x00 否 0x01 是需做到变位上送
        $outVoltage = $this->binToDecimal(substr($newStr, 0,4),2,0.1);//输出电压,精确到小数点后一位；待机置零
        $outElectric = $this->binToDecimal(substr($newStr, 4,4),2,0.1);//输出电流,精确到小数点后一位；待机置零
        $gunTemperature = hexdec(substr($newStr, 8,2));//枪线温度,整形，偏移量-50；待机置零
        $gunCode = $this->binToDecimal(substr($newStr, 10,16),8,1);//枪线编码,没有置零
        $socStatus = hexdec(substr($newStr, 26,2));//待机置零；交流桩置零
        $batteryPackTemperature = hexdec(substr($newStr, 28,2));//电池组最高温度,整形，偏移量-50 ºC；待机置零；交流桩置零
        $chargeTime = $this->binToDecimal(substr($newStr, 30,4),2,1);//累计充电时间,单位：min；待机置零
        $residueTime = $this->binToDecimal(substr($newStr, 34,4),2,1);//剩余时间,单位：min；待机置零,交流桩置零
        $chargeNumber = $this->binToDecimal(substr($newStr, 38,8),4,0.0001);//充电度数,精确到小数点后四位；待机置零
        $lossNumber = $this->binToDecimal(substr($newStr, 46,8),4,0.0001);//计损充电度数,精确到小数点后四位；待机置零 未设置计损比例时等于充电度数
        $chargedAmount = $this->binToDecimal(substr($newStr, 54,8),4,0.0001);//已充金额,精确到小数点后四位；待机置零（电费+服务费）*计损充电度数
        $hardwareFailure = $this->binToDecimal(substr($newStr, 62,4),2,1);//硬件故障,
        $backInfo = '';
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$pileNumber."' && is_delete=1")->row();
        if(!$pileInfo){
            //$backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'00',$pileNumber.'000001');
            $backData = ['code'=>1,'msg'=>'设备不存在','back_data'=>$backInfo];
            return $backData;
        }
        $pileGunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$pileGunNumber)->row();
        $gunStatusList =['00'=>0,'01'=>2,'02'=>1,'03'=>3];
        $gunInsertStatusList =['00'=>0,'01'=>1,'02'=>2];
        $addGunStatus = 0;
        //设置枪的状态
        if(!$pileGunInfo){
            $addGunStatus = 1;
            $pileGunInfo = [
                'pile_id'=>$pileInfo['id'],
                'is_status'=>$gunStatusList[$pileStatus],
                'is_homing'=>$gunInsertStatusList[$pileGunStatus],
                'remark'=>'',
                'error_remark'=>'',
                'num'=>$pileGunNumber,
                'create_time'=>date("Y-m-d H:i:s"),
                'update_time'=>date("Y-m-d H:i:s")
            ];
            $gunId = $db->insert('jy_charge_pile_gun')->cols($pileGunInfo)->query();
            if(!$gunId){
                //$backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'00',$pileNumber.'000001');
                $backData = ['code'=>1,'msg'=>'充电枪不存在，添加充电枪失败','back_data'=>$backInfo];
                return $backData;
            }
            $pileGunInfo['id'] = $gunId;
        }else{
            //枪的状态发生改变
            if($pileGunInfo['is_status'] != $gunStatusList[$pileStatus] || $pileGunInfo['is_homing'] != $gunInsertStatusList[$pileGunStatus]){
                $gunUpdateData = [
                    'is_status'=> $gunStatusList[$pileStatus],
                    'is_homing'=>$gunInsertStatusList[$pileGunStatus],
                    'update_time'=>date("Y-m-d H:i:s")
                ];
                $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$pileGunInfo['id'])->cols($gunUpdateData)->query();
                if($gunUpdateResult) $addGunStatus = 1;
            }
        }

        //获取最后一条记录
        $inputWhere = 'pile_id='.$pileInfo['id']." && gun_id=".$pileGunInfo['id'];
        $pileInputData = $db->select('*')->from('jy_pile_input_data')->where($inputWhere)->row();
        $addLogTime = 20;
        $billType = 0;
        //充电状态
        if($pileStatus == '03'){
            $addLogTime = 5;
            $billType = 1;
        }
        if((!$pileInputData || strtotime($pileInputData['create_time']) < time()-(60*$addLogTime)) || $addGunStatus){
            $inputData = [
                'order_sn'=>$orderSn,
                'pile_number'=>$pileNumber,
                'pile_gun_number'=>$pileGunNumber,
                'pile_status'=>$pileStatus,
                'pile_gun_status'=>$pileGunStatus,
                'pile_gun_insert'=>$pileGunInsert,
                'out_voltage'=>$outVoltage,
                'out_electric'=>$outElectric,
                'gun_temperature'=>$gunTemperature,
                'gun_code'=>$gunCode,
                'soc_status'=>$socStatus,
                'battery_pack_temperature'=>$batteryPackTemperature,
                'charge_time'=>$chargeTime,
                'residue_time'=>$residueTime,
                'charge_number'=>$chargeNumber,
                'loss_number'=>$lossNumber,
                'charged_amount'=>$chargedAmount,
                'hardware_failure'=>$hardwareFailure,
                'gun_id'=>$pileGunInfo['id'],
            ];
            //添加充电订单和充电订单子记录
            if($billType == 1 && $orderSn){
                $backOrderData = $this->addOrderInfo($db,$orderSn,$pileInfo,$pileGunNumber,$chargeTime,$residueTime,$chargeNumber,$lossNumber,$chargedAmount,$inputData,1);
                if($backOrderData['code'] > 0){
                    //$backInfo = $this->setBackData($data['sor_number'],$data['encryption'],'00',$pileNumber.'000001');
                    return ['code'=>$backOrderData['code'],'msg'=>$backOrderData['msg'],'back_data'=>$backInfo];
                }
            }
            //添加提交数据记录
            if(!$pileInputData || strtotime($pileInputData['create_time']) < time()-(60*$addLogTime)){
                $this->addInputBillData($db,$pileInfo,$pileGunInfo,$billType,$inputData,$recordId);
            }
            //添加枪操作记录
            if($addGunStatus){
                $this->addGunOperationRecord($db,$pileInfo,$pileGunInfo,1,$inputData,['code'=>0,'msg'=>'修改枪状态成功'],$recordId);
            }

        }

        return ['code'=>0,'msg'=>'操作实时上传数据成功','back_data'=>''];
    }

    /**
     * 添加插入记录
     * @param $db
     * @param $pileInfo
     * @param $pileGunInfo
     * @param $billType
     * @param $inputData
     * @param $recordId
     * @param string $remark
     * @return mixed
     */
    function addInputBillData($db,$pileInfo,$pileGunInfo,$billType,$inputData,$recordId,$remark=''){
        return  $db->insert('jy_pile_input_data')->cols([
            'pile_id'=>$pileInfo['id'],
            'station_id'=>$pileInfo['station_id'],
            'gun_id'=>isset($pileGunInfo['id']) ? $pileGunInfo['id'] : 0,
            'num'=>isset($pileGunInfo['num']) ? $pileGunInfo['num'] : 0,
            'record_id'=>$recordId,
            'input_data'=>json_encode($inputData,JSON_UNESCAPED_UNICODE),
            'operation_type'=>$billType,
            'remark'=>$remark,
            'create_time'=>date("Y-m-d H:i:s")
        ])->query();
    }

    /**
     * 添加枪的操作记录
     * @param $db
     * @param $pileInfo
     * @param $operationType
     * @param $inputData
     * @param $backData
     * @param $recordId
     * @param string $remark
     * @return mixed
     */
    function addGunOperationRecord($db,$pileInfo,$gunInfo,$operationType,$inputData,$backData,$recordId,$remark='',$relationId=0){
        $outResult = 0;
        if(isset($backData['code']) && $backData['code'] > 0) $outResult = $backData['code'];
        return  $db->insert('jy_gun_operation_record')->cols([
            'pile_id'=>$pileInfo['id'],
            'station_id'=>$pileInfo['station_id'],
            'gun_id'=>$gunInfo['id'],
            'num'=>$gunInfo['num'],
            'operation_type'=>$operationType,
            'input_data'=>json_encode($inputData,JSON_UNESCAPED_UNICODE),
            'out_data'=>json_encode($backData,JSON_UNESCAPED_UNICODE),
            'out_result'=>$outResult,
            'record_id'=>$recordId,
            'remark'=>$remark,
            'relation_id'=>$relationId,
            'create_time'=>date("Y-m-d H:i:s")
        ])->query();
    }

    /**
     * 添加实时订单记录
     * @param $db
     * @param $orderSn
     * @param $pileInfo
     * @param $pileGunNumber
     * @param $chargeTime
     * @param $residueTime
     * @param $chargeNumber
     * @param $lossNumber
     * @param $chargedAmount
     * @return array
     */
    function addOrderInfo($db,$orderSn,$pileInfo,$pileGunNumber,$chargeTime,$residueTime,$chargeNumber,$lossNumber,$chargedAmount,$inputData,$type){
        $orderInfo  = $db->select('*')->from('jy_pile_order')->where("order_sn=".$orderSn)->row();
        if(!$orderInfo) return ['code'=>1,'msg'=>'找不到对应的订单'];
        if($orderInfo['status'] == 0){
            $db->update('jy_pile_order')->cols(['status'=>1,'update_time'=>date("Y-m-d H:i:s")])->where('id='.$orderInfo['id'])->query();
        }
        //记录时间间隔设置
        $checkTime = 0;
        //不设置记录时间间隔
        if($checkTime == 0){
            $orderSonData = [
                'uid'=>$orderInfo['uid'],
                'order_id'=>$orderInfo['id'],
                'pile_id'=>$pileInfo['id'],
                'station_id'=>$orderInfo['station_id'],
                'order_sn'=>$orderSn,
                'pile_gun_number'=>$pileGunNumber,
                'gun_id'=>$inputData['gun_id'],
                'charge_time'=>hexdec($chargeTime),
                'residue_time'=>hexdec($residueTime),
                'charge_number'=>hexdec($chargeNumber) * 0.0001,
                'loss_number'=>hexdec($lossNumber) * 0.0001,
                'charged_amount'=>hexdec($chargedAmount) * 0.0001,
                'create_time'=>date("Y-m-d H:i:s"),
                'update_time'=>date("Y-m-d H:i:s"),
                'type'=>$type,
                'content_data'=>json_encode($inputData,JSON_UNESCAPED_UNICODE),
            ];
            $orderSonId = $db->insert('jy_pile_order_son')->cols($orderSonData)->query();
            if($orderSonId){
                $orderSonData['id'] = $orderSonId;
                $this->userNowMoneyCheck($db,$orderSonData,$orderSonId);
                return ['code'=>0,'msg'=>'记入记录成功','data'=>$orderSonData];
            }else{
                return ['code'=>1,'msg'=>'记入记录失败'];
            }
        }else{
            $orderSonInfo = $db->select('*')->from('jy_pile_order_son')->where("order_id=".$orderInfo['id'])->orderByDESC(['id'])->row();
            if(!$orderSonInfo || (strtotime($orderSonInfo['create_time']) + $checkTime * 60) < time() ){
                $orderSonData = [
                    'uid'=>$orderInfo['uid'],
                    'order_id'=>$orderInfo['id'],
                    'pile_id'=>$pileInfo['id'],
                    'station_id'=>$orderInfo['station_id'],
                    'order_sn'=>$orderSn,
                    'pile_gun_number'=>$pileGunNumber,
                    'gun_id'=>$inputData['gun_id'],
                    'charge_time'=>hexdec($chargeTime),
                    'residue_time'=>hexdec($residueTime),
                    'charge_number'=>hexdec($chargeNumber) * 0.0001,
                    'loss_number'=>hexdec($lossNumber) * 0.0001,
                    'charged_amount'=>hexdec($chargedAmount) * 0.0001,
                    'create_time'=>date("Y-m-d H:i:s"),
                    'update_time'=>date("Y-m-d H:i:s"),
                    'type'=>$type,
                    'content_data'=>json_encode($inputData,JSON_UNESCAPED_UNICODE),
                ];
                $orderSonId = $db->insert('jy_pile_order_son')->cols($orderSonData)->query();
                if($orderSonId){
                    $orderSonData['id'] = $orderSonId;
                    $this->userNowMoneyCheck($db,$orderSonData,$orderSonId);
                    return ['code'=>0,'msg'=>'记入记录成功','data'=>$orderSonData];
                }else{
                    return ['code'=>1,'msg'=>'记入记录失败'];
                }
            }else{
                return ['code'=>2,'msg'=>'没有记入记录'];
            }
        }
    }

    /**
     * 用户账户判断
     * @param $db
     * @param $orderSonData
     * @param $orderSonId
     * @return array
     */
    function userNowMoneyCheck($db,$orderSonData,$orderSonId){
        $balanceDefaultPayInfo = $db->select('*')->from('jy_system_config')->where("config_key = 'default_balance_pay_status'")->row();
        //开启默认余额支付
        if($balanceDefaultPayInfo['config_value'] == 1){
            $userInfo = $db->select('*')->from('jy_user')->where("id=".$orderSonData['uid'])->row();
            //dump($userInfo);
            $userCostStatusInfo = $db->select('*')->from('jy_system_config')->where("config_key = 'pay_order_user_cost_status'")->row();
            if($userCostStatusInfo){
                $userCostWhere = 'user_id='.$orderSonData['uid'].' && station_id='.$orderSonData['station_id'].' && pile_id='.$orderSonData['pile_id'].' && is_status=1 && is_delete=1 && start_time<= "'.date("Y-m-d H:i:s").'" && end_time >= "'.date("Y-m-d H:i:s").'"';
                $userCostInfo = $db->select('*')->from('jy_user_pile_cost')->where($userCostWhere)->row();
                //dump($userCostInfo);
                if($userCostInfo){
                    $orderSonData['charged_amount'] = bcmul($orderSonData['charge_number'] , ($userCostInfo['cost_electricity'] +  $userCostInfo['cost_number']),2);
                }
            }
            //账户金额不足
            if($userInfo['now_money'] <= ($orderSonData['charged_amount'] + 0.1)){
                $checkWhere = 'event_type="stop_charge" && order_id='.$orderSonData['order_id'].' && user_id='.$orderSonData['uid'].' && station_id='.$orderSonData['station_id'].' && pile_id='.$orderSonData['pile_id'].' && gun_id='.$orderSonData['gun_id'];
                $eventInfo = $db->select('*')->from('jy_timer_event')->where($checkWhere)->row();
                //没有对应的定时器记录
                if(!$eventInfo){
                    $orderSonId = $db->insert('jy_timer_event')->cols([
                        'event_type'=>'stop_charge',
                        'is_execute'=>0,
                        'order_id'=>$orderSonData['order_id'],
                        'record_id'=>$orderSonId,
                        'user_id'=>$orderSonData['uid'],
                        'pile_id'=>$orderSonData['pile_id'],
                        'station_id'=>$orderSonData['station_id'],
                        'gun_id'=>$orderSonData['gun_id'],
                        'create_time'=>date("Y-m-d H:i:s"),
                        'update_time'=>date("Y-m-d H:i:s"),
                    ])->query();
                }
            }
            return ['code'=>0];
        }else{
            return ['code'=>0];
        }
    }

    /**
     * 添加总订单
     * @param $db
     * @param $orderSn
     * @param $pileInfo
     * @param $pileGunNumber
     * @param int $uid
     * @return array
     */
    function addOrder($db,$orderSn,$pileInfo,$pileGunNumber,$userInfo = [],$dataInfo=[]){
        $costInfo = $db->select('*')->from('jy_charge_pile_cost')->where("id=".$pileInfo['cost_id'])->row();
        $orderData = [
            'uid'=>$userInfo['id'],
            'spread_uid'=>$userInfo['spread_uid'],
            'order_sn'=>$orderSn,
            'pile_id'=>$pileInfo['id'],
            'station_id'=>$pileInfo['station_id'],
            'pile_gun_number'=>$pileGunNumber,
            'gun_id'=>$dataInfo['gun_id'],
            'start_time'=>isset($dataInfo['start_time']) ? $dataInfo['start_time'] : '',
            'charge_cost'=>$pileInfo['charge_cost'],
            'service_cost'=>$pileInfo['service_cost'],
            'peak_electric_cost'=>$pileInfo['peak_electric_cost'],
            'peak_service_cost'=>$pileInfo['peak_service_cost'],
            'flat_electric_cost'=>$pileInfo['flat_electric_cost'],
            'flat_service_cost'=>$pileInfo['flat_service_cost'],
            'valley_electric_cost'=>$pileInfo['valley_electric_cost'],
            'valley_service_cost'=>$pileInfo['valley_service_cost'],
            'cost_id'=>$pileInfo['cost_id'],
            'cost_content'=>$costInfo['cost_value'],
            'paid'=>0,
            'status'=>0,
            'is_del'=>0,
            'is_system_del'=>0,
            'create_time'=>date("Y-m-d H:i:s"),         //创建时间
            'update_time'=>date("Y-m-d H:i:s"),         //修改建时间
            'battery_type'=>$dataInfo['battery_type'],
            'start_type'=>$dataInfo['start_type'],
        ];
        $orderId = $db->insert('jy_pile_order')->cols($orderData)->query();
        $orderData['id'] = $orderId;
        return $orderData;
    }

    /**
     * 获取订单编号
     * @return string
     */
    function getOrderNumber(){
        list($msec, $sec) = explode(' ', microtime());
        $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
        $rand1 = mt_rand(10000, max(intval($msec * 10000) + 10000, 98369));
        $rand2 = mt_rand(10000, 99999);
        $orderSn = '100' . $msectime . mt_rand(10000, max(intval($msec * 10000) + 10000, 98369)).$rand1.$rand2;
        if(strlen($orderSn) > 32){
            $orderSn = substr($orderSn,0,32);
        }else if(strlen($orderSn) < 32){
            $orderSn = str_pad($orderSn,32,'0',STR_PAD_RIGHT);
        }
        return $orderSn;
    }

    /**
     * 充电握手
     * @param $db
     * @param $data
     * @param $insertId
     * @return array
     */
    function chargingHandshake($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['communication_protocol'] = substr($dataInfo, 48,6);//BMS 通信协议版本号
        $data['battery_type'] = substr($dataInfo, 54,2);//BMS 电池类型
        $data['battery_capacity'] = $this->binToDecimal(substr($dataInfo, 56,4),2,0.1);//BMS 整车动力蓄电池系统额定容量
        $data['battery_voltage'] = $this->binToDecimal(substr($dataInfo, 60,4),2,0.1);//BMS 整车动力蓄电池系统额定总电压
        $data['battery_manufacturer'] = chr($this->binToDecimal(substr($dataInfo, 64,8),4,1));//BMS 电池生产厂商名称
        $data['battery_sort_number'] = $this->binToDecimal(substr($dataInfo, 72,8),4,1);//BMS 电池组序号
        $data['battery_produce_year'] = substr($dataInfo, 80,2);//BMS 电池组生产日期年
        $data['battery_produce_month'] = substr($dataInfo, 82,2);//BMS 电池组生产日期月
        $data['battery_produce_day'] = substr($dataInfo, 84,2);//BMS 电池组生产日期日
        $data['battery_use_number'] = $this->binToDecimal(substr($dataInfo, 86,6),3,1);//BMS 电池组充电次数
        $data['battery_produce_status'] = substr($dataInfo, 92,2);//BMS 电池组产权标识
        $data['cart_number'] = substr($dataInfo, 94,34);//BMS 车辆识别码
        $data['battery_version'] = substr($dataInfo, 128,16);//BMS 软件版本号
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $data['pile_id'] = isset($pileInfo['id']) ? $pileInfo['id']: 0;
        $data['order_id'] = isset($orderInfo['id']) ? $orderInfo['id']: 0;
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        $backData = ['code'=>0,'msg'=>'握手成功','back_data'=>''];
        $remark = '充电握手';
        $updateContent = $data;
        unset($updateContent['order_sn']);
        unset($updateContent['pile_number']);
        unset($updateContent['pile_gun_number']);
        $updateData = ['update_time'=>date("Y-m-d H:i:s"),'charge_hand_content'=>json_encode($updateContent,JSON_UNESCAPED_UNICODE)];
        $orderResult = $db->update('jy_pile_order')->cols($updateData)->where('id='.$orderInfo['id'])->query();
        if(!$orderResult) $remark = '修改订单充电握手内容失败';
        //添加枪操作记录
        $this->addGunOperationRecord($db,$pileInfo,$gunInfo,2,json_encode($data,JSON_UNESCAPED_UNICODE),$backData,$insertId,$remark,$data['order_id']);
        return $backData;
    }

    /**
     * 充电桩配置参数
     * @param $db
     * @param $data
     * @param $insertId
     * @return array
     */
    function chargePileGunSetParameter($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['battery_max_voltage'] = substr($dataInfo, 48,4);//BMS 单体动力蓄电池最高允许充电电压
        $data['battery_max_electric'] = substr($dataInfo, 52,4);//BMS 最高允许充电电流
        $data['battery_nominal_all_number'] = substr($dataInfo, 56,4);//BMS 动力蓄电池标称总能量
        $data['max_all_voltage'] = substr($dataInfo, 60,4);//BMS 最高允许充电总电压
        $data['max_temperature'] = chr(hexdec(substr($dataInfo, 64,2)));//BMS 最高允许温度
        $data['battery_charge_status'] = substr($dataInfo, 66,4);//BMS 整车动力蓄电池荷电状态
        $data['battery_now_voltage'] = substr($dataInfo, 70,4);//BMS 整车动力蓄电池当前电池电压
        $data['pile_max_voltage'] = substr($dataInfo, 74,4);//电桩最高输出电压
        $data['pile_min_voltage'] = substr($dataInfo, 78,4);//电桩最低输出电压
        $data['pile_max_electric'] = substr($dataInfo, 82,4);//电桩最大输出电流
        $data['pile_min_electric'] = substr($dataInfo, 86,4);//电桩最小输出电流
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $data['pile_id'] = isset($pileInfo['id']) ? $pileInfo['id']: 0;
        $data['order_id'] = isset($orderInfo['id']) ? $orderInfo['id']: 0;
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        $backData = ['code'=>0,'msg'=>'充电桩参数配置成功','back_data'=>''];
        $remark = '充电桩参数配置';
        $updateContent = $data;
        unset($updateContent['order_sn']);
        unset($updateContent['pile_number']);
        unset($updateContent['pile_gun_number']);
        $updateData = ['update_time'=>date("Y-m-d H:i:s"),'charge_set_parameter'=>json_encode($updateContent,JSON_UNESCAPED_UNICODE)];
        $orderResult = $db->update('jy_pile_order')->cols($updateData)->where('id='.$orderInfo['id'])->query();
        if(!$orderResult) $remark = '充电桩参数配置失败';
        //添加枪操作记录
        $this->addGunOperationRecord($db,$pileInfo,$gunInfo,3,json_encode($data,JSON_UNESCAPED_UNICODE),$backData,$insertId,$remark,$data['order_id']);
        return $backData;
    }

    /**
     * 充电结束
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function pileEndCharge($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['stop_charge_status'] = substr($dataInfo, 48,2);//BMS 中止荷电状态 SOC
        $data['single_battery_min_voltage'] = substr($dataInfo, 50,4);//BMS 动力蓄电池单体最低电压
        $data['single_battery_max_voltage'] = substr($dataInfo, 54,4);//BMS 动力蓄电池单体最高电压
        $data['single_battery_min_temperature'] = substr($dataInfo, 58,4);//BMS 动力蓄电池最低温度
        $data['single_battery_max_temperature'] = substr($dataInfo, 62,4);//BMS 动力蓄电池单体最高温度
        $data['charge_time'] = substr($dataInfo, 66,4);//电桩累计充电时间
        $data['out_energy'] = substr($dataInfo, 70,4);//电桩输出能量
        $data['motor_number'] = substr($dataInfo, 74,4);//电桩充电机编号
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $data['pile_id'] = isset($pileInfo['id']) ? $pileInfo['id']: 0;
        $data['order_id'] = isset($orderInfo['id']) ? $orderInfo['id']: 0;
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        $backData = ['code'=>0,'msg'=>'充电结束','back_data'=>''];
        $remark = '充电桩结束';
        $updateContent = $data;
        unset($updateContent['order_sn']);
        unset($updateContent['pile_number']);
        unset($updateContent['pile_gun_number']);
        $updateData = [
            'update_time'=>date("Y-m-d H:i:s"),
            'charge_time'=>$data['charge_time'],
            'charge_number'=>$data['out_energy'],
            'status'=>2,
            'end_time'=>date("Y-m-d H:i:s"),
            'charge_end_content'=>json_encode($updateContent,JSON_UNESCAPED_UNICODE),
        ];
        //订单已经支付或者订单已经过了结束充电状态
        if($orderInfo['paid'] == 1 || $orderInfo['status'] > 2){
            $orderResult = true;
        }else{
            $orderResult = $db->update('jy_pile_order')->cols($updateData)->where('id='.$orderInfo['id'])->query();
            $gunUpdateData = ['is_status'=>1,'update_time'=>date("Y-m-d H:i:s")];
            $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
        }
        if(!$orderResult) $remark = '充电桩结束设置失败';
        //添加枪操作记录
        $this->addGunOperationRecord($db,$pileInfo,$gunInfo,4,json_encode($data,JSON_UNESCAPED_UNICODE),$backData,$insertId,$remark,$data['order_id']);
        return $backData;
    }

    /**
     * 错误报文
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function addErrorContent($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['battery_charge_error_00'] = substr($dataInfo, 48,4);//接收 SPN2560=0x00 的充电机辨识报文超时
        $data['battery_charge_error_AA'] = substr($dataInfo, 52,4);//接收 SPN2560=0xAA 的充电机辨识报文超时
        $data['reserved_info1'] = substr($dataInfo, 56,8);//预留位
        $data['charger_error_info'] = substr($dataInfo, 72,4);//接收充电机的时间同步和充电机最大输出能力报文超时
        $data['charger_completes_charging'] = substr($dataInfo, 76,4);//接收充电机完成充电准备报文超时
        $data['reserved_info2'] = substr($dataInfo, 80,8);//预留位
        $data['charger_status'] = substr($dataInfo, 88,4);//接收充电机充电状态报文超时
        $data['charger_stop_status'] = substr($dataInfo, 92,4);//接收充电机中止充电报文超时
        $data['reserved_info3'] = substr($dataInfo, 96,8);//预留位
        $data['charger_count_status'] = substr($dataInfo, 104,4);//接收充电机充电统计报文超时
        $data['charger_status'] = substr($dataInfo, 108,12);//BMS 其他
        $data['bms_car_time_out'] = substr($dataInfo, 120,4);//接收 BMS 和车辆的辨识报文超时
        $data['reserved_info4'] = substr($dataInfo, 124,12);//预留位
        $data['charger_parameter_status'] = substr($dataInfo, 136,4);//接收电池充电参数报文超时
        $data['charger_completes_time_out'] = substr($dataInfo, 140,4);//接收 BMS 完成充电准备报文超时
        $data['reserved_info5'] = substr($dataInfo, 144,8);//预留位
        $data['battery_charge_status'] = substr($dataInfo, 152,4);//接收电池充电总状态报文超时
        $data['battery_charge_request'] = substr($dataInfo, 156,4);//接收电池充电要求报文超时
        $data['bms_stop_charge'] = substr($dataInfo, 160,4);//接收 BMS 中止充电报文超时
        $data['reserved_info6'] = substr($dataInfo, 164,4);//预留位
        $data['bms_charge_count'] = substr($dataInfo, 168,4);//接收 BMS 充电统计报文超时
        $data['other_error'] = substr($dataInfo, 172,12);//充电机其他
        $backData = ['code'=>0,'msg'=>'接受错误报文成功','back_data'=>''];
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        $getErrorInfo = $this->backErrorInfo($data);
        $errorResult = $db->insert('jy_charge_pile_error')->cols([
            'pile_id'=>isset($pileInfo['id']) ? $pileInfo['id'] : 0,
            'station_id'=>isset($pileInfo['station_id']) ? $pileInfo['station_id'] : 0,
            'gun_id'=>isset($gunInfo['id']) ? $gunInfo['id'] : 0,
            'error_type'=>$getErrorInfo['key_name'],
            'error_type_name'=>$getErrorInfo['error_value'],
            'relation_id'=>isset($orderInfo['id']) ? $orderInfo['id'] : 0,
            'error_data'=>json_encode($data,JSON_UNESCAPED_UNICODE),
            'create_time'=>date("Y-m-d H:i:s")
        ])->query();
        if(!$errorResult) $backData['msg'] = '接受错误报文记录失败';
        return $backData;
    }

    /**
     * 返回报文错误相关信息
     * @param $errorData
     * @return array
     */
    function backErrorInfo($errorData){
        $keyName = '';
        $status = '';
        foreach ($errorData as $key=>$value){
            if($value != '00'){
                $keyName = $key;
                $status = $value;
                break;
            }
        }
        $valueList = [
            '00'=>'正常',
            '01'=>'超时',
            '10'=>'不可信状态',
        ];
        $keyList=[
            'battery_charge_error_00'=>'接收 SPN2560=0x00 的充电机辨识报文超时',
            'battery_charge_error_AA'=>'接收 SPN2560=0xAA 的充电机辨识报文超时',
            'reserved_info1'=>'预留位',
            'charger_error_info'=>'接收充电机的时间同步和充电机最大输出能力报文超时',
            'charger_completes_charging'=>'接收充电机完成充电准备报文超时',
            'reserved_info2'=>'预留位',
            'charger_status'=>'接收充电机充电状态报文超时',
            'charger_stop_status'=>'接收充电机中止充电报文超时',
            'reserved_info3'=>'预留位',
            'charger_count_status'=>'接收充电机充电统计报文超时',
            'charger_status'=>'BMS 其他',
            'bms_car_time_out'=>'接收 BMS 和车辆的辨识报文超时',
            'reserved_info4'=>'预留位',
            'charger_parameter_status'=>'接收电池充电参数报文超时',
            'charger_completes_time_out'=>'接收 BMS 完成充电准备报文超时',
            'reserved_info5'=>'预留位',
            'battery_charge_status'=>'接收电池充电总状态报文超时',
            'battery_charge_request'=>'接收电池充电要求报文超时',
            'bms_stop_charge'=>'接收 BMS 中止充电报文超时',
            'reserved_info6'=>'预留位',
            'bms_charge_count'=>'接收 BMS 充电统计报文超时',
            'other_error'=>'充电机其他',
        ];
        return [
            'key_name'=>$keyName,
            'error_value'=>(isset($keyList[$keyName]) ? $keyList[$keyName] : '').(isset($valueList[$status]) ? $valueList[$status] : ''),
        ];
    }

    /**
     * 充电阶段 BMS 中止
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function bmsStopCharge($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['bms_stop_reason'] = substr($dataInfo, 48,2);//BMS 中止充电原因
        $data['bms_stop_fault'] = substr($dataInfo, 50,4);//BMS 中止充电故障原因
        $data['bms_stop_error'] = substr($dataInfo, 54,2);//BMS 中止充电错误原因
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        if($orderInfo['paid'] == 1 || $orderInfo['status'] >= 2){
            $backData = ['code'=>1,'msg'=>'当前订单不是处在充电状态','back_data'=>''];
        }else{
            $data['pile_id'] = isset($pileInfo['id']) ? $pileInfo['id']: 0;
            $data['order_id'] = isset($orderInfo['id']) ? $orderInfo['id']: 0;
            $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
            $backData = ['code'=>0,'msg'=>'BMS终止充电','back_data'=>''];
            $remark = '充电阶段 BMS 中止';
            //修改数据
            $updateData = [
                'update_time'=>date("Y-m-d H:i:s"),
                'mark'=>'充电阶段 BMS 中止',
            ];
            $orderResult = $db->update('jy_pile_order')->cols($updateData)->where('id='.$orderInfo['id'])->query();
            if(!$orderResult) $remark = '充电阶段 BMS 中止失败';
            if($gunInfo['is_status'] !=1){
                $gunUpdateData = ['is_status'=>1,'update_time'=>date("Y-m-d H:i:s")];
                $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
            }
            //添加枪操作记录
            $this->addGunOperationRecord($db,$pileInfo,$gunInfo,5,json_encode($data,JSON_UNESCAPED_UNICODE),$backData,$insertId,$remark,$data['order_id']);
        }

        return $backData;

    }

    /**
     * 充电阶段充电机中止
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function machineryStopCharge($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['bms_stop_reason'] = substr($dataInfo, 48,2);//充电机 中止充电原因
        $data['bms_stop_fault'] = substr($dataInfo, 50,4);//充电机 中止充电故障原因
        $data['bms_stop_error'] = substr($dataInfo, 54,2);//充电机 中止充电错误原因
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $data['pile_id'] = isset($pileInfo['id']) ? $pileInfo['id']: 0;
        $data['order_id'] = isset($orderInfo['id']) ? $orderInfo['id']: 0;
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        if($orderInfo['paid'] == 1 || $orderInfo['status'] >= 2){
            $backData = ['code'=>1,'msg'=>'当前订单不是处在充电状态','back_data'=>''];
        }else{
            $backData = ['code'=>0,'msg'=>'BMS终止充电','back_data'=>''];
            $remark = '充电阶段充电机中止';
            //修改数据
            $updateData = [
                'update_time'=>date("Y-m-d H:i:s"),
                'mark'=>'充电阶段充电机中止',
            ];
            $orderResult = $db->update('jy_pile_order')->cols($updateData)->where('id='.$orderInfo['id'])->query();
            if(!$orderResult) $remark = '充电阶段充电机中止失败';
            if($gunInfo['is_status'] !=1){
                $gunUpdateData = ['is_status'=>1,'update_time'=>date("Y-m-d H:i:s")];
                $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
            }
            //添加枪操作记录
            $this->addGunOperationRecord($db,$pileInfo,$gunInfo,6,json_encode($data,JSON_UNESCAPED_UNICODE),$backData,$insertId,$remark,$data['order_id']);
        }
        return $backData;

    }

    /**
     * 充电过程 BMS 需求、充电机输出
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function bmsOutData($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['bms_voltage_need'] = $this->binToDecimal(substr($dataInfo, 48,4),2,0.1);//BMS 电压需求
        $data['bms_electric_need'] = $this->binToDecimal(substr($dataInfo, 52,4),2,0.1);//BMS 电流需求
        $data['charge_model'] = substr($dataInfo, 56,2);//BMS 充电模式
        $data['bms_voltage_measure'] = $this->binToDecimal(substr($dataInfo, 58,4),2,0.1);//BMS 充电电压测量值
        $data['bms_electric_measure'] = $this->binToDecimal(substr($dataInfo, 62,4),2,0.1);//BMS 充电电流测量值
        $data['simple_max_voltage'] = $this->binToDecimal(substr($dataInfo, 66,4),2,1);//BMS 最高单体动力蓄电池电压及组号
        $data['current_charge_status'] = $this->binToDecimal(substr($dataInfo, 70,2),1,1);//BMS 当前荷电状态 SOC（ %）
        $data['bms_estimate_surplus_time'] = $this->binToDecimal(substr($dataInfo, 72,4),2,1);//BMS 估算剩余充电时间
        $data['pile_voltage_out'] = $this->binToDecimal(substr($dataInfo, 76,4),2,0.1);//电桩电压输出值
        $data['pile_electric_out'] = $this->binToDecimal(substr($dataInfo, 80,4),2,0.1);//电桩电流输出值
        $data['charge_time'] = $this->binToDecimal(substr($dataInfo, 84,4),2,1);//累计充电时间
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $data['pile_id'] = isset($pileInfo['id']) ? $pileInfo['id']: 0;
        $data['order_id'] = isset($orderInfo['id']) ? $orderInfo['id']: 0;
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        $sonOrderInfo = $db->select('*')->from('jy_pile_order_son')->where("order_id=".$orderInfo['id']." && pile_gun_number=".$data['pile_gun_number'])->orderByDESC(['id'])->row();
        //添加数据
        $addTime = 0;
        $orderSonId = true;
        if(!$sonOrderInfo || (strtotime($sonOrderInfo['create_time']) + $addTime * 60) < time()){
            $orderSonData = [
                'uid'=>$orderInfo['uid'],
                'order_id'=>$orderInfo['id'],
                'pile_id'=>$pileInfo['id'],
                'station_id'=>$orderInfo['station_id'],
                'order_sn'=>$data['order_sn'],
                'pile_gun_number'=>$data['pile_gun_number'],
                'gun_id'=>$gunInfo['gun_id'],
                'charge_time'=>hexdec($data['charge_time']),
                'residue_time'=>hexdec($data['bms_estimate_surplus_time']),
                'charge_number'=>hexdec($data['current_charge_status']),
                'loss_number'=>0,
                'charged_amount'=>0,
                'create_time'=>date("Y-m-d H:i:s"),
                'update_time'=>date("Y-m-d H:i:s"),
                'type'=>2,
                'content_data'=>json_encode($data,JSON_UNESCAPED_UNICODE),
            ];
            $orderSonId = $db->insert('jy_pile_order_son')->cols($orderSonData)->query();
            if($orderSonId){
                $this->userNowMoneyCheck($db,$orderSonData,$orderSonId);
            }
        }
        //设置充电枪为充电状态
        if($gunInfo['is_status'] != 3){
            $gunUpdateData = ['is_status'=> 3,'update_time'=>date("Y-m-d H:i:s")];
            $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
            $this->addGunOperationRecord($db,$pileInfo,$gunInfo,7,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);
        }
        $backData = ['code'=>0,'msg'=>'记录充电过程BMS需求与充电机输出成功','back_data'=>''];
        if(!$orderSonId) $backData = ['code'=>1,'msg'=>'记录充电过程BMS需求与充电机输出失败','back_data'=>''];
        return $backData;
    }

    /**
     * 充电过程 BMS 信息
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function bmsChargeInfo($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号 交易流水号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号 桩编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['bms_simple_max_voltage'] = substr($dataInfo, 48,2);//BMS 最高单体动力蓄电池电压所在编号
        $data['max_battery_temperature'] = substr($dataInfo, 50,2);//BMS 最高动力蓄电池温度
        $data['max_temperature_spot'] = substr($dataInfo, 52,2);//最高温度检测点编号
        $data['min_battery_temperature'] = substr($dataInfo, 54,2);//最低动力蓄电池温度
        $data['min_temperature_spot'] = substr($dataInfo, 56,2);//最低动力蓄电池温度检测点编号
        $data['simple_voltage_abnormal'] = substr($dataInfo, 58,4);//BMS 单体动力蓄电池电压过高/过低(<00>：=正常; <01>：=过高; <10>：=过低)
        $data['all_battery_charging_status'] = substr($dataInfo, 62,4);//BMS 整车动力蓄电池荷电状态SOC 过高/过低(<00>：=正常; <01>：=过高; <10>：=过低)
        $data['battery_electric_status'] = substr($dataInfo, 66,4);//BMS 动力蓄电池充电过电流 (<00>：=正常; <01>：=过流; <10>：=不可信状态)
        $data['all_battery_temperature'] = substr($dataInfo, 70,4);//BMS 动力蓄电池温度过高 过高/过低(<00>：=正常; <01>：=过流; <10>：=过低)
        $data['battery_insulation_status'] = substr($dataInfo, 74,4);//BMS 动力蓄电池绝缘状态 (<00>：=正常; <01>：=过流; <10>：=过低)
        $data['battery_link_out_status'] = substr($dataInfo, 78,4);//BMS 动力蓄电池组输出连接器连接状态 (<00>：=正常; <01>：=过流; <10>：=过低)
        $data['stop_charge_status'] = substr($dataInfo, 82,4);//充电禁止 (<00>：=禁止; <01>：=允许
        //获取设备及充电枪信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $msgInfo = $db->select('*')->from('jy_bms_msg_record')->where("pile_id='".$pileInfo['id']."' && relation_id=".$orderInfo['id'])->row();
        $addTime = 1;
        if(!$msgInfo || (strtotime($msgInfo['create_time']) + 60 * $addTime) < time()){
            $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
            $addResult = $this->addBmsMsg($db,$pileInfo,$gunInfo,$orderInfo,$data,$insertId);
            if(!$addResult){
                return ['code'=>1,'msg'=>'充电过程 BMS 信息记录失败','back_data'=>''];
            }else{
                return ['code'=>0,'msg'=>'记录充电过程 BMS 信息记录成功','back_data'=>''];
            }
        }else{
            return ['code'=>2,'msg'=>'充电过程 BMS 信息记录','back_data'=>''];
        }
    }

    /**
     * 添加Bms信息记录
     * @param $db
     * @param $pileInfo
     * @param $gunInfo
     * @param $orderInfo
     * @param $contentData
     * @param $insertId
     * @param string $remark
     * @return mixed
     */
    function addBmsMsg($db,$pileInfo,$gunInfo,$orderInfo,$contentData,$insertId,$remark=''){
        $recordResult =  $db->insert('jy_bms_msg_record')->cols([
            'pile_id'=>$pileInfo['id'],
            'station_id'=>$pileInfo['station_id'],
            'gun_id'=>$gunInfo['id'],
            'num'=>$gunInfo['num'],
            'type'=>1,
            'record_id'=>$insertId,
            'relation_id'=>$orderInfo['id'],
            'content_data'=>json_encode($contentData,JSON_UNESCAPED_UNICODE),
            'remark'=>$remark,
            'create_time'=>date("Y-m-d H:i:s")
        ])->query();
        return $recordResult;
    }

    /**
     * 充电桩主动申请启动充电
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function pileApplyCharge($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号
        $data['pile_gun_number'] = substr($dataInfo, 14,2);//获取设备枪号
        $data['start_mode'] = substr($dataInfo, 16,2);//启动方式 0x01 表示通过刷卡启动充电 0x02 表求通过帐号启动充电（暂不支持） 0x03 表示vin码启动充电
        $data['need_password'] = substr($dataInfo, 18,2);//是否需要密码
        $data['pile_card_account'] = substr($dataInfo, 20,16);//账号或者物理卡号
        $data['pile_card_password'] = substr($dataInfo, 36,32);//输入密码
        $data['pile_vin_code'] = substr($dataInfo, 68,34);//VIN 码
        $orderSn = $this->getOrderNumber();
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        //启动方式查询 01 表示通过刷卡启动充电
        if($data['start_mode'] == '01'){
            $userCard = $db->select('*')->from('jy_user_card')->where("card_number='".$data['pile_card_account']."' && is_delete=1")->row();
            //没有对应的卡
            $backData = [];
            if(!$userCard){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>1,'msg'=>'卡号不存在','back_data'=>$backInfo];
            //卡被冻结
            }else if($userCard['status'] == 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'02';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>2,'msg'=>'该卡被冻结','back_data'=>$backInfo];
            //卡中存在未结算记录
            }else{
                //账号余额不足
                if($userCard['user_money'] <= 0){
                    $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'03';
                    $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                    $backData = ['code'=>4,'msg'=>'该卡余额不足','back_data'=>$backInfo];
                }else{
                    $userInfo = $db->select('*')->from('jy_user')->where("id=".$userCard['user_id'])->row();
                    //该卡不存在用户
                    if(!$userInfo){
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01';
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>5,'msg'=>'用户不存在','back_data'=>$backInfo];
                    }else{
                        //判断是否存在为结账订单
                        $orderWhere = 'uid='.$userInfo['id']." && is_del= 0 && paid=0 && status < 3 && start_type=1";
                        $orderCheck = $db->select('*')->from('jy_pile_order')->where($orderWhere)->row();
                        if($orderCheck){
                            $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'04';
                            $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                            $backData = ['code'=>3,'msg'=>'该卡存在未结账记录','back_data'=>$backInfo];
                        }else{
                            $otherData = ['start_time'=>date("Y-m-d H:i:s"),'battery_type'=>'FFH','start_type'=>1,'gun_id'=>$gunInfo['gun_id']];
                            $cardUpdateData = ['status'=>2,'update_time'=>date("Y-m-d H:i:s")];
                            //$db->beginTrans();
                            //$db->commitTrans();
                            //$db->rollBackTrans();
                            $gunUpdateData = ['is_status'=> 3,'update_time'=>date("Y-m-d H:i:s")];
                            //修改枪的状态
                            $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
                            //添加枪操作记录
                            $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);
                            //添加订单
                            $db->beginTrans();
                            $orderResult = $this->addOrder($db,$orderSn,$pileInfo,$data['pile_gun_number'],$userInfo,$otherData);
                            //修改卡的状态
                            $cardUpdateResult = $db->update('jy_user_card')->where('id='.$userCard['id'])->cols($cardUpdateData)->query();
                            if(isset($orderResult['id']) && $orderResult['id'] > 0 && $cardUpdateResult){
                                $db->commitTrans();
                                //添加订单操作记录
                                $orderRecordResult = $db->insert('jy_order_status')->cols([
                                    'order_id'=>$orderResult['id'],
                                    'user_id'=>$orderResult['uid'],
                                    'type'=>1,
                                    'remark'=>'用户创建订单',
                                    'create_time'=>date("Y-m-d H:i:s"),
                                ])->query();
                                $userMoney = dechex($userCard['user_money'] * 100);
                                $userMoney = $this->numberToBin($userMoney,8);
                                /*
                                $moneyLength = strlen((string)$userMoney);
                                if($moneyLength > 8){
                                    $userMoney = substr($userMoney,0,8);
                                }else if($moneyLength < 8){
                                    $userMoney = str_pad($userMoney,8,0,STR_PAD_LEFT);
                                }
                                */
                                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].$userMoney.'01'.'00';
                                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                                $backData = ['code'=>0,'msg'=>'启动充电成功','back_data'=>$backInfo];
                            }else{
                                $db->rollBackTrans();
                                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'0C';
                                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                                $backData = ['code'=>6,'msg'=>'启动充电添加订单失败','back_data'=>$backInfo];
                            }
                        }
                    }
                }
            }
            //添加充电桩操作记录
            $this->addOperationRecord($db,$pileInfo,3,$data,$backData,$insertId,$backData['msg']);
            return $backData;

        //账号登录
        }else if($data['start_mode'] == '02'){
            $userInfo = $db->select('*')->from('jy_user')->where("account=".$data['pile_card_account'])->row();
            //不存在用户
            if(!$userInfo){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>1,'msg'=>'账户不存在','back_data'=>$backInfo];
            //账户被冻结
            }else if($userInfo['status'] == 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'02';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>2,'msg'=>'该账户被冻结','back_data'=>$backInfo];
            //密码不一致
            }else if( $data['need_password'] == "01" && $userInfo['pwd'] != $data['pile_card_password']){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'07';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>7,'msg'=>'密码错误','back_data'=>$backInfo];
            //账户余额不足
            }else if($userInfo['now_money'] <= 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'03';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>4,'msg'=>'账户余额不足','back_data'=>$backInfo];
            }else{
                //判断是否存在为结账订单
                $orderWhere = 'uid='.$userInfo['id']." && is_del= 0 && paid=0 && status < 3 && start_type=2";
                $orderCheck = $db->select('*')->from('jy_pile_order')->where($orderWhere)->row();
                if($orderCheck){
                    $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'04';
                    $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                    $backData = ['code'=>3,'msg'=>'该用户在未结账订单','back_data'=>$backInfo];
                }else{
                    $otherData = ['start_time'=>date("Y-m-d H:i:s"),'battery_type'=>'FFH','start_type'=>2,'gun_id'=>$gunInfo['gun_id']];
                    //$db->beginTrans();
                    //$db->commitTrans();
                    //$db->rollBackTrans();
                    $orderResult = $this->addOrder($db,$orderSn,$pileInfo,$data['pile_gun_number'],$userInfo,$otherData);
                    $gunUpdateData = ['is_status'=> 3,'update_time'=>date("Y-m-d H:i:s")];
                    $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
                    //添加枪操作记录
                    $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);
                    if(isset($orderResult['id']) && $orderResult['id'] > 0){
                        //添加订单操作记录
                        $orderRecordResult = $db->insert('jy_order_status')->cols([
                            'order_id'=>$orderResult['id'],
                            'user_id'=>$orderResult['uid'],
                            'type'=>1,
                            'remark'=>'用户创建订单',
                            'create_time'=>date("Y-m-d H:i:s"),
                        ])->query();
                        $userMoney = dechex($userInfo['now_money'] * 100);
                        $userMoney = $this->numberToBin($userMoney,8);
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].$userMoney.'01'.'00';
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>0,'msg'=>'启动充电成功','back_data'=>$backInfo];
                    }else{
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'0C';
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>1,'msg'=>'启动充电添加订单失败','back_data'=>$backInfo];
                    }
                }
            }
            //添加充电桩操作记录
            $this->addOperationRecord($db,$pileInfo,3,$data,$backData,$insertId,$backData['msg']);
            return $backData;
        //vin码登录
        }else if($data['start_mode'] == '03'){
            $userInfo = $db->select('*')->from('jy_user')->where("vin_number=".$data['pile_vin_code'])->row();
            //不存在用户
            if(!$userInfo){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>1,'msg'=>'账户不存在','back_data'=>$backInfo];
                //账户被冻结
            }else if($userInfo['status'] == 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'02';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>2,'msg'=>'该账户被冻结','back_data'=>$backInfo];
                //密码不一致
            }else if( $data['need_password'] == "01" && $userInfo['pwd'] != $data['pile_card_password']){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'07';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>7,'msg'=>'密码错误','back_data'=>$backInfo];
                //账户余额不足
            }else if($userInfo['now_money'] <= 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'03';
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>4,'msg'=>'账户余额不足','back_data'=>$backInfo];
            }else{
                //判断是否存在为结账订单
                $orderWhere = 'uid='.$userInfo['id']." && is_del= 0 && paid=0 && status < 3 && start_type=3";
                $orderCheck = $db->select('*')->from('jy_pile_order')->where($orderWhere)->row();
                if($orderCheck){
                    $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'04';
                    $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                    $backData = ['code'=>3,'msg'=>'该用户在未结账订单','back_data'=>$backInfo];
                }else{
                    $otherData = ['start_time'=>date("Y-m-d H:i:s"),'battery_type'=>'FFH','start_type'=>3,'gun_id'=>$gunInfo['gun_id']];
                    //$db->beginTrans();
                    //$db->commitTrans();
                    //$db->rollBackTrans();
                    $orderResult = $this->addOrder($db,$orderSn,$pileInfo,$data['pile_gun_number'],$userInfo,$otherData);
                    $gunUpdateData = ['is_status'=> 3,'update_time'=>date("Y-m-d H:i:s")];
                    $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
                    //添加枪操作记录
                    $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);
                    if(isset($orderResult['id']) && $orderResult['id'] > 0){
                        //添加订单操作记录
                        $orderRecordResult = $db->insert('jy_order_status')->cols([
                            'order_id'=>$orderResult['id'],
                            'user_id'=>$orderResult['uid'],
                            'type'=>1,
                            'remark'=>'用户创建订单',
                            'create_time'=>date("Y-m-d H:i:s"),
                        ])->query();
                        $userMoney = dechex($userInfo['now_money'] * 100);
                        $userMoney = $this->numberToBin($userMoney,8);
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].$userMoney.'01'.'00';
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>0,'msg'=>'启动充电成功','back_data'=>$backInfo];
                    }else{
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'0C';
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>1,'msg'=>'启动充电添加订单失败','back_data'=>$backInfo];
                    }
                }
            }
            //添加充电桩操作记录
            $this->addOperationRecord($db,$pileInfo,3,$data,$backData,$insertId,$backData['msg']);
            return $backData;
        }else{
            $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01';
            $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
            return ['code'=>1,'msg'=>'启动方式不存在','back_data'=>$backInfo];
        }
    }

    /**
     * 读取实时监测数据
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function getChargePileDataInfo($pileInfo,$data){
        $contentData = $pileInfo['device_sn'].$data['pile_gun']['num'];
        $backInfo = $this->setBackData('0000','00','12',$contentData);
        $backData = ['code'=>0,'msg'=>'读取实时数据','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 运营平台启动充电桩
     * @param $db
     * @param $userInfo
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function platformStartCharge($db,$userInfo,$pileInfo,$data){
        $userMoney = dechex($userInfo['now_money'] * 100);
        $userMoney = $this->numberToBin($userMoney,8);
        /*
        $moneyLength = strlen((string)$userMoney);
        if($moneyLength > 8){
            $userMoney = substr($userMoney,0,8);
        }else if($moneyLength < 8){
            $userMoney = str_pad($userMoney,8,0,STR_PAD_LEFT);
        }
        */
        $contentData = $data['order_info']['order_sn'].$pileInfo['device_sn'].$data['pile_gun']['num'].$data['user_card']['logical_card'].$data['user_card']['card_number'].$userMoney;
        $backInfo = $this->setBackData('007C','00','34',$contentData);
        $backData = ['code'=>0,'msg'=>'发送启动充电','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 远程启机命令回复
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function remoteCommandChargeReply($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号 交易流水号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号 桩编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['start_result'] = substr($dataInfo, 48,2);//设备启动结果 0x00失败 0x01成功
        $data['start_error'] = substr($dataInfo, 48,2);//失败原因
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        if($orderInfo['start_type'] != 4){
            $backData = ['code'=>4,'msg'=>'该订单不是远程启动订单','back_data'=>''];
        }else{
            $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
            $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
            //启动成功
            if($data['start_result'] == '01'){
                //启动充电桩充电
                if($orderInfo['status'] == 0){
                    $orderData = [
                        'status'=>1,
                        'update_time'=>date("Y-m-d H:i:s"),
                        'charge_hand_content'=>json_encode($data,JSON_UNESCAPED_UNICODE),
                    ];
                    if($orderInfo['start_time'] == '') $orderData['start_time'] = date("Y-m-d H:i:s");
                    $orderResult = $db->update('jy_pile_order')->cols($orderData)->where('id='.$orderInfo['id'])->query();
                    $orderRecordResult = $db->insert('jy_order_status')->cols([
                        'order_id'=>$orderInfo['id'],
                        'user_id'=>$orderInfo['uid'],
                        'type'=>2,
                        'remark'=>'充电桩启动充电，修改订单为充电状态',
                        'create_time'=>date("Y-m-d H:i:s"),
                    ])->query();
                }
                if($gunInfo['is_status'] != 3 || $gunInfo['error_remark'] != ''){
                    $gunData = ['is_status'=>3,'error_remark'=>'','update_time'=>date("Y-m-d H:i:s")];
                    $gunResult = $db->update('jy_charge_pile_gun')->cols($gunData)->where('id='.$gunInfo['id'])->query();
                    $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);;
                }
                $backData = ['code'=>0,'msg'=>'充电启动成功','back_data'=>''];
            }else if($data['start_result'] == '00'){
                //启动充电桩充电
                if($orderInfo['status'] == 1){
                    $orderData = [
                        'status'=>0,
                        'update_time'=>date("Y-m-d H:i:s"),
                        'charge_hand_content'=>json_encode($data,JSON_UNESCAPED_UNICODE),
                    ];
                    $orderResult = $db->update('jy_pile_order')->cols($orderData)->where('id='.$orderInfo['id'])->query();
                    $orderRecordResult = $db->insert('jy_order_status')->cols([
                        'order_id'=>$orderInfo['id'],
                        'user_id'=>$orderInfo['uid'],
                        'type'=>2,
                        'remark'=>'充电桩启动充电失败，修改订单为待充电状态',
                        'create_time'=>date("Y-m-d H:i:s"),
                        'content_info'=>json_encode($data,JSON_UNESCAPED_UNICODE),
                    ])->query();
                }
                if($gunInfo['is_status'] == 3 || $gunInfo['error_remark'] == ''){
                    $gunData = ['is_status'=>1,'error_remark'=>'充电启动失败','update_time'=>date("Y-m-d H:i:s")];
                    $gunResult = $db->update('jy_charge_pile_gun')->cols($gunData)->where('id='.$gunInfo['id'])->query();
                    $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'启动充电失败，修改枪为空闲状态'],$insertId);;
                }
                $backData = ['code'=>1,'msg'=>'充电启动失败','back_data'=>''];
            }else{
                $backData = ['code'=>2,'msg'=>'启动参数有误','back_data'=>''];
            }
        }

        return $backData;

    }

    /**
     * 运营平台停止充电
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function platformStopCharge($pileInfo,$data){
        $contentData = $pileInfo['device_sn'].$data['pile_gun']['num'];
        $backInfo = $this->setBackData('0003','00','36',$contentData);
        $backData = ['code'=>0,'msg'=>'发送停止充电','back_data'=>$backInfo];
        return $backData;
    }
	
    /**
     * 远程停机命令回复
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function remoteStopChargeReply($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['pile_gun_number'] = substr($dataInfo, 14,2);//获取设备枪号
        $data['stop_result'] = substr($dataInfo, 16,2);//停止结果 0x00失败 0x01成功
        $data['stop_error'] = substr($dataInfo, 18,2);//失败原因
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        //获取该充电桩对应的订单号
        $orderWhere = "pile_id=".$pileInfo['id']." && pile_gun_number=".$data['pile_gun_number']." && start_type=4 && status = 1";
        $orderInfo = $db->select('*')->from('jy_pile_order')->where($orderWhere)->orderByDESC(['id'])->row();
        //充电停止成功
        if($data['stop_result'] == '01'){
            $orderResult = true;
            //修改订单状态
            if($orderInfo['status'] < 2 && $orderInfo['paid'] != 1){
                $orderData = [
                    'status'=>2,
                    'update_time'=>date("Y-m-d H:i:s"),
                    'charge_end_content'=>json_encode($data,JSON_UNESCAPED_UNICODE),
                ];
                if($orderInfo['end_time'] == '') $orderData['end_time'] = date("Y-m-d H:i:s");
                $orderResult = $db->update('jy_pile_order')->cols($orderData)->where('id='.$orderInfo['id'])->query();
                $orderRecordResult = $db->insert('jy_order_status')->cols([
                    'order_id'=>$orderInfo['id'],
                    'user_id'=>$orderInfo['uid'],
                    'type'=>3,
                    'remark'=>'充电桩停止充电，修改订单为停止充电状态',
                    'create_time'=>date("Y-m-d H:i:s"),
                    'content_info'=>json_encode($data,JSON_UNESCAPED_UNICODE),
                ])->query();
            }
            //修改充电桩状态
            if($gunInfo['is_status'] != 1 && $orderResult){
                $gunData = ['is_status'=>1,'update_time'=>date("Y-m-d H:i:s")];
                $gunResult = $db->update('jy_charge_pile_gun')->cols($gunData)->where('id='.$gunInfo['id'])->query();
                $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);;
            }
            $backData = ['code'=>0,'msg'=>'充电停止成功','back_data'=>''];
        }else if($data['start_result'] == '00'){
            $backData = ['code'=>1,'msg'=>'充电停止失败','back_data'=>''];
        }else{
            $backData = ['code'=>2,'msg'=>'停止参数有误','back_data'=>''];
        }
        return $backData;

    }

    /**
     * 交易记录
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function pileTransactionRecords($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号 交易流水号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号 桩编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['start_time'] = $this->cP56TimeToFormatTime(substr($dataInfo, 48,14));//开始时间 CP56Time2a 格式
        $data['end_time'] = $this->cP56TimeToFormatTime(substr($dataInfo, 62,14));//结束时间 CP56Time2a 格式

        //$data['tip_price'] = $this->binToDecimal('D0FB0100',4,0.00001);//尖单价
        $data['tip_price'] = $this->binToDecimal(substr($dataInfo, 76,8),4,0.00001);//尖单价
        $data['tip_number'] = $this->binToDecimal(substr($dataInfo, 84,8),4,0.0001);//尖电量
        $data['tip_loss_number'] = $this->binToDecimal(substr($dataInfo, 92,8),4,0.0001);//计损尖电量
        $data['tip_money'] = $this->binToDecimal(substr($dataInfo, 100,8),4,0.0001);//尖金额

        $data['peak_price'] = $this->binToDecimal(substr($dataInfo, 108,8),4,0.00001);//峰单价
        $data['peak_number'] = $this->binToDecimal(substr($dataInfo, 116,8),4,0.0001);//峰电量
        $data['peak_loss_number'] = $this->binToDecimal(substr($dataInfo, 124,8),4,0.0001);//计损峰电量
        $data['peak_money'] = $this->binToDecimal(substr($dataInfo, 132,8),4,0.0001);//峰金额

        $data['flat_price'] = $this->binToDecimal(substr($dataInfo, 140,8),4,0.00001);//平单价
        $data['flat_number'] = $this->binToDecimal(substr($dataInfo, 148,8),4,0.0001);//平电量
        $data['flat_loss_number'] = $this->binToDecimal(substr($dataInfo, 156,8),4,0.0001);//计损平电量
        $data['flat_money'] = $this->binToDecimal(substr($dataInfo, 164,8),4,0.0001);//平金额

        $data['valley_price'] = $this->binToDecimal(substr($dataInfo, 172,8),4,0.00001);//谷单价
        $data['valley_number'] = $this->binToDecimal(substr($dataInfo, 180,8),4,0.0001);//谷电量
        $data['valley_loss_number'] = $this->binToDecimal(substr($dataInfo, 188,8),4,0.0001);//计损谷电量
        $data['valley_money'] = $this->binToDecimal(substr($dataInfo, 196,8),4,0.0001);//谷金额

        $data['all_start_electric'] = $this->binToDecimal(substr($dataInfo, 204,10),4,0.0001);//电表总起值
        $data['all_end_electric'] = $this->binToDecimal(substr($dataInfo, 214,10),4,0.0001);//电表总止值
        $data['all_electric'] = $this->binToDecimal(substr($dataInfo, 224,8),4,0.0001);//总电量
        $data['all_loss_electric'] = $this->binToDecimal(substr($dataInfo, 232,8),4,0.0001);//计损总电量
        $data['consume_money'] = $this->binToDecimal(substr($dataInfo, 240,8),4,0.0001);//消费金额
        $data['cart_only_status'] = substr($dataInfo, 248,34);//电动汽车唯一标识
        $data['start_type'] = substr($dataInfo, 282,2);//交易标识
        $data['transaction_time'] = $this->cP56TimeToFormatTime(substr($dataInfo, 284,14));//交易日期、时间
        $data['stop_reason'] = substr($dataInfo, 298,2);//停止原因
        $data['card_number'] = substr($dataInfo, 300,16);//物理卡号

        //设置数据
        $orderInfoData = $data;
        unset($orderInfoData['order_sn']);
        unset($orderInfoData['pile_number']);
        $orderInfoData['insert_id'] = $insertId;
        //获取订单数据
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $orderInfoData['order_id'] = isset($orderInfo['id']) ? $orderInfo['id'] : 0;
        $orderInfoData['user_id'] = isset($orderInfo['uid']) ? $orderInfo['uid'] : 0;
        $orderInfoData['pile_id'] = isset($orderInfo['pile_id']) ? $orderInfo['pile_id'] : 0;
        $orderInfoData['station_id'] = isset($orderInfo['station_id']) ? $orderInfo['station_id'] : 0;
        $orderInfoData['gun_id'] = isset($orderInfo['gun_id']) ? $orderInfo['gun_id'] : 0;
        $orderData = [
            //'status'=>2,
            'update_time'=>date("Y-m-d H:i:s"),
            'pile_price'=>$data['consume_money'],
        ];
        if($orderInfo['status'] == 1) $orderData['status'] = 2;
        $db->beginTrans();
        $orderInfoResult = $db->insert('jy_pile_order_info')->cols($orderInfoData)->query();
        $updateOrderResult = $db->update('jy_pile_order')->cols($orderData)->where('id='.$orderInfo['id'])->query();
        if($orderInfoResult && $updateOrderResult){
            $db->commitTrans();
            $contentData = $data['order_sn'].'00';
            $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'40',$contentData);
            $backData = ['code'=>0,'msg'=>'增加交易记录成功','back_data'=>$backInfo];
        }else{
            $db->rollBackTrans();
            $contentData = $data['order_sn'].'01';
            $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'40',$contentData);
            $backData = ['code'=>1,'msg'=>'增加交易记录失败','back_data'=>$backInfo];
        }
        return  $backData;
    }

    /**
     * 10进制转16进制
     * @param $number
     * @param $ratio
     * @param $length
     * @return bool|string
     */
    function decimalToBin($number,$ratio,$length){
        $setNumber = dechex(bcmul($number , $ratio,0));
        $numberLength = strlen((string)$setNumber);
        if($numberLength > $length){
            $setNumber = substr($setNumber,0,8);
        }else if($numberLength < $length){
            $setNumber = str_pad($setNumber,8,0,STR_PAD_LEFT);
        }
        return $setNumber;
    }


    /**
     * 远程账户余额更新
     * @param $userInfo
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function updateUserMoney($userInfo,$pileInfo,$data){
        $contentData = $pileInfo['device_sn'].$data['pile_gun']['num'].$data['user_card']['card_number'].dechex($userInfo['now_money']*100);
        $backInfo = $this->setBackData('0006','00','42',$contentData);
        $backData = ['code'=>0,'msg'=>'远程账户余额更新','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 余额更新应答
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function userMoneyResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['card_number'] = substr($dataInfo, 14,16);//物理卡号
        $data['update_result'] = substr($dataInfo, 30,2);//修改结果
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number'])->row();
        if($data['update_result'] == '00'){
            $backData = ['code'=>0,'msg'=>'余额更新应答成功','back_data'=>''];
        }else if($data['update_result'] == '01'){
            $backData = ['code'=>1,'msg'=>'余额更新应答失败','back_data'=>''];
        }else if($data['update_result'] == '02'){
            $backData = ['code'=>2,'msg'=>'卡号错误','back_data'=>''];
        }else{
            $backData = ['code'=>3,'msg'=>'返回状态错误','back_data'=>''];
        }
        $this->addOperationRecord($db,$pileInfo,5,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 离线卡数据同步
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function updateCardData($pileInfo,$data){
        if($data['card_info']['count'] > 15) $data['card_info']['count'] = 15;
        $contentData = $pileInfo['device_sn'].$data['card_info']['count'];
        $i = 1;
        foreach ($data['card_info']['list'] as $key=>$value){
            if($i>15){
                break;
            }else{
                $contentData = isset($value['logical_card']) ? ($contentData.$value['logical_card']) : $contentData;
                $contentData = isset($value['card_number']) ? ($contentData.$value['card_number']) : $contentData;
                $i++;
            }
        }
        $backInfo = $this->setBackData('0007','00','44',$contentData);
        $backData = ['code'=>0,'msg'=>'离线卡数据同步','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 卡数据同步应答
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function userCardResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['update_result'] = substr($dataInfo, 14,2);//保存结果
        $data['error_info'] = substr($dataInfo, 16,2);//修改结果
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number'])->row();
        if($data['update_result'] == '00'){
            $backData = ['code'=>0,'msg'=>'卡数据同步应答成功','back_data'=>''];
        }else if($data['update_result'] == '01'){
            $backData = ['code'=>1,'msg'=>'卡数据同步应答失败','back_data'=>''];
        }else{
            $backData = ['code'=>2,'msg'=>'返回状态错误','back_data'=>''];
        }
        $this->addOperationRecord($db,$pileInfo,6,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 离线卡数据同步
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function deleteCardData($pileInfo,$data){
        if($data['card_info']['count'] > 24) $data['card_info']['count'] = 24;
        $contentData = $pileInfo['device_sn'].$data['card_info']['count'];
        $i = 1;
        foreach ($data['card_info']['list'] as $key=>$value){
            if($i>24){
                break;
            }else{
                $contentData = isset($value['logical_card']) ? ($contentData.$value['logical_card']) : $contentData;
                $contentData = isset($value['card_number']) ? ($contentData.$value['card_number']) : $contentData;
                $i++;
            }
        }
        $backInfo = $this->setBackData('0007','00','46',$contentData);
        $backData = ['code'=>0,'msg'=>'离线卡数据清除','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 离线卡数据清除应答
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function deleteUserCardResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $cardData = substr($dataInfo, 14);//获取设备编号 桩编号
        $strLength = strlen($cardData) - 14;
        $setCardData = [];
        $k = 0;
        for ($i = 0;$i<$strLength;$i = $i + 20){
            if($k > 25){
                break;
            }else{
                $setCardData[] = [
                    'card_number'=>substr($cardData, $i,16),
                    'delete_status'=>substr($cardData, ($i+16),2),
                    'error_info'=>substr($cardData, ($i+18),2),
                ];
            }
            $k++;
        }
        $data['delete_result'] = $setCardData;//保存结果
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number'])->row();
        $backData = ['code'=>0,'msg'=>'离线卡数据清除应答成功','back_data'=>''];
        $this->addOperationRecord($db,$pileInfo,7,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 离线卡数据查询
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function selectCardData($pileInfo,$data){
        if($data['card_info']['count'] > 26) $data['card_info']['count'] = 26;
        $contentData = $pileInfo['device_sn'].$data['card_info']['count'];
        $i = 1;
        foreach ($data['card_info']['list'] as $key=>$value){
            if($i>26){
                break;
            }else{
                $contentData = $contentData.$value['card_number'];
                $i++;
            }
        }
        $backInfo = $this->setBackData('0007','00','48',$contentData);
        $backData = ['code'=>0,'msg'=>'离线卡数据查询','back_data'=>$backInfo];
        return $backData;
    }


    /**
     * 离线卡数据查询应答
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function selectUserCardResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $cardData = substr($dataInfo, 14);//获取设备编号 桩编号
        $strLength = strlen($cardData) - 14;
        $setCardData = [];
        $k = 0;
        for ($i = 0;$i<$strLength;$i = $i + 18){
            if($k > 26){
                break;
            }else{
                $setCardData[] = [
                    'card_number'=>substr($cardData, $i,16),
                    'select_status'=>substr($cardData, ($i+16),2),
                ];
            }
            $k++;
        }
        $data['delete_result'] = $setCardData;//保存结果
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number'])->row();
        $backData = ['code'=>0,'msg'=>'离线卡数据查询应答成功','back_data'=>''];
        $this->addOperationRecord($db,$pileInfo,8,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 充电桩工作参数设置
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function setPileParameter($pileInfo,$data){
        if($data['pile_status'] == 1){
            $pileStatus = "00";
        }else{
            $pileStatus = "01";
        }
        $contentData = $pileInfo['device_sn'].$pileStatus.$data['max_put'];
        $backInfo = $this->setBackData('0008','00','52',$contentData);
        $backData = ['code'=>0,'msg'=>'充电桩工作参数设置','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 充电桩工作参数设置应答
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function setPileParameterResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['set_result'] = substr($dataInfo, 14,2);//设置结果
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number'])->row();
        //设置失败
        if($data['set_result'] == '00'){
            if($pileInfo['is_status'] == 1){
                $updatePileData = ['is_status'=>0,'update_time'=>date("Y-m-d H:i:s")];
            }else{
                $updatePileData = ['is_status'=>1,'update_time'=>date("Y-m-d H:i:s")];
            }
            $updateResult = $db->update('jy_charge_pile')->cols($updatePileData)->where('id='.$pileInfo['id'])->query();
        }
        $backData = ['code'=>0,'msg'=>'充电桩工作参数设置应答成功','back_data'=>''];
        $this->addOperationRecord($db,$pileInfo,9,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 对时设置
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function setPileTime($pileInfo,$data){
        $contentData = $pileInfo['device_sn'].$this->formatTimeToCP56Time($data['set_time']);
        $backInfo = $this->setBackData('00DF','00','56',$contentData);
        $backData = ['code'=>0,'msg'=>'对时设置','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 对时设置应答
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function setPileTimeResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['get_time'] = cP56TimeToFormatTime(substr($dataInfo, 14,14));//当前时间
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number'])->row();
        $getTime = time();
        $checkTime = strtoupper($data['get_time']);
        $errorNumber = 5;
        //在指定的误差范围内
        if(abs($checkTime - $getTime) <= $errorNumber){
            $backData = ['code'=>0,'msg'=>'充电桩工作参数设置应答成功','back_data'=>''];
        }else{
            $backData = ['code'=>1,'msg'=>'充电桩工作参数设置应答-时间误差超出范围','back_data'=>'','pile_info'=>$pileInfo];
        }

        $this->addOperationRecord($db,$pileInfo,10,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 计费模型设置
     * @param $db
     * @param $data
     * @param $insertId
     * @return array
     */
    function setPileBillingMode($pileInfo,$modeInfo){
        $costList = strtoupper(dechex($pileInfo['charge_cost']*100000));
        $costList = $costList.strtoupper(dechex($pileInfo['service_cost']*100000));
        $costList = $costList.strtoupper(dechex($pileInfo['peak_electric_cost']*100000));
        $costList = $costList.strtoupper(dechex($pileInfo['peak_service_cost']*100000));
        $costList = $costList.strtoupper(dechex($pileInfo['flat_electric_cost']*100000));
        $costList = $costList.strtoupper(dechex($pileInfo['flat_service_cost']*100000));
        $costList = $costList.strtoupper(dechex($pileInfo['valley_electric_cost']*100000));
        $costList = $costList.strtoupper(dechex($pileInfo['valley_service_cost']*100000));

        //设置各个情况的费率
        $dataInfo = $pileInfo['device_sn'].$modeInfo['billing_mode'].$costList.'00';
        $i = 1;
        $getModelList = json_decode($modeInfo['cost_value'],true);
        $modelListData = [];
        foreach ($getModelList as $key=>$value){
            $modelListData[$value['name']] = $value['value'];
        }
        for($i=1;$i<=48;$i++){
            $dataInfo = isset($modelListData['model-'.$i]) ? $dataInfo.$modelListData['model-'.$i] : '01';
        }
        $backInfo = $this->setBackData('0025','00','58',$dataInfo);
        $backData = ['code'=>0,'msg'=>'设置收费模型','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 计费模型应答
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function pileBillingModeResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['set_result'] = substr($dataInfo, 14,2);//设置结果
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number'])->row();
        //设置失败
        if($data['set_result'] == '00'){
            if($pileInfo['cost_status'] == 1){
                $updatePileData = ['cost_status'=>0,'update_time'=>date("Y-m-d H:i:s")];
                $updateResult = $db->update('jy_charge_pile')->cols($updatePileData)->where('id='.$pileInfo['id'])->query();
            }
            $backData = ['code'=>1,'msg'=>'计费模型设置失败','back_data'=>''];
        }else if($data['set_result'] == '01'){
            if($pileInfo['cost_status'] == 0){
                $updatePileData = ['is_status'=>1,'update_time'=>date("Y-m-d H:i:s")];
                $updateResult = $db->update('jy_charge_pile')->cols($updatePileData)->where('id='.$pileInfo['id'])->query();
            }
            $backData = ['code'=>0,'msg'=>'计费模型设置成功','back_data'=>''];
        }else{
            $backData = ['code'=>2,'msg'=>'计费模型设置结果返回错误','back_data'=>''];
        }
        $this->addOperationRecord($db,$pileInfo,11,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 地锁数据上送
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function getFloorLockData($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['pile_gun_number'] = substr($dataInfo, 14,2);//获取设备枪号
        $data['lock_status'] = substr($dataInfo, 16,2);//车位锁状态 0x00：未到位状态 0x55：升锁到位状态 0xFF：降锁到位状态
        $data['cart_status'] = substr($dataInfo, 18,2);//车位状态 0x00：无车辆 0xFF：停放车辆
        $data['battery_status'] = hexdec(substr($dataInfo, 20,2));//地锁电量状态  百分比值0~100
        $data['alarm_status'] = substr($dataInfo, 22,2);//报警状态  0x00：正常无报警 0xFF：待机状态摇臂破坏 0x55：摇臂升降异常(未到位)
        //获取设备信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        $lockWhere = "pile_id='".$pileInfo['id']."' && gun_id=".$gunInfo['id'];
        $lockInfo = $db->select('*')->from('jy_pile_floor_lock')->where($lockWhere)->row();
        $saveData = ['update_time'=>date("Y-m-d H:i:s"),'battery_status'=>$data['battery_status']];
        //车位锁状态
        if($data['lock_status'] == '55'){
            $saveData['is_status'] = 1;
        }else if($data['lock_status'] == 'FF'){
            $saveData['is_status'] = 2;
        }else{
            $saveData['is_status'] = 3;
        }
        //车位状态
        if($data['lock_status'] == '00'){
            $saveData['cart_status'] = 2;
        }else{
            $saveData['cart_status'] = 1;
        }
        //报警状态
        if($data['lock_status'] == '00'){
            $saveData['alarm_status'] = 1;
        }else if($data['lock_status'] == 'FF'){
            $saveData['alarm_status'] = 2;
        }else{
            $saveData['alarm_status'] = 3;
        }
        //判断是否有记录
        if(!$lockInfo){
            $saveData['station_id'] = $pileInfo['station_id'];
            $saveData['pile_id'] = $pileInfo['id'];
            $saveData['gun_id'] = $gunInfo['id'];
            $saveData['gun_num'] = $gunInfo['num'];
            $saveData['create_time'] = date("Y-m-d H:i:s");
            $lockResult = $db->insert('jy_pile_floor_lock')->cols($saveData)->query();
            $lockInfo = $saveData;
            $lockInfo['id'] = $lockResult ? $lockResult : 0;
        }else{
            $lockInfo['is_status'] = $saveData['is_status'];
            $lockInfo['cart_status'] = $saveData['cart_status'];
            $lockInfo['alarm_status'] = $saveData['alarm_status'];
            $lockResult = $db->update('jy_pile_floor_lock')->cols($saveData)->where('id='.$lockInfo['id'])->query();
        }
        //添加地桩锁记录
        if($lockResult){
            $backData = ['code'=>0,'msg'=>'更新地锁状态成功','back_data'=>''];
        }else{
            $backData = ['code'=>1,'msg'=>'更新地锁状态失败','back_data'=>''];
        }
        $this->addLockOperationRecord($db,$lockInfo,$data,$backData,$insertId,$backData['msg']);
        return $backData;

    }

    /**
     * 添加地锁操作记录
     * @param $db
     * @param $lockInfo
     * @param $inputData
     * @param $backData
     * @param $recordId
     * @param string $remark
     * @return mixed
     */
    function addLockOperationRecord($db,$lockInfo,$inputData,$backData,$recordId,$remark=''){
        $outResult = 0;
        if(isset($backData['code']) && $backData['code'] > 0) $outResult = $backData['code'];
        return  $db->insert('jy_lock_operation_record')->cols([
            'lock_id'=>$lockInfo['id'],
            'gun_id'=>$lockInfo['gun_id'],
            'pile_id'=>$lockInfo['pile_id'],
            'station_id'=>$lockInfo['station_id'],
            'operation_type'=>$lockInfo['is_status'],
            'out_data'=>json_encode($backData,JSON_UNESCAPED_UNICODE),
            'out_result'=>$outResult,
            'record_id'=>$recordId,
            'remark'=>$remark,
            'input_data'=>json_encode($inputData,JSON_UNESCAPED_UNICODE),
            'create_time'=>date("Y-m-d H:i:s")
        ])->query();
    }

    /**
     * 遥控地锁升锁与降锁命令
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function setFloorLockStatus($pileInfo,$data){
        if($data['lock_status'] == 1){  //升锁
            $lockStatus = "55";
        }else{
            $lockStatus = "FF";
        }
        $contentData = $pileInfo['device_sn'].$data['gun_info']['num'].$lockStatus.'00000000';
        $backInfo = $this->setBackData('0001','00','62',$contentData);
        $backData = ['code'=>0,'msg'=>'遥控地锁升锁与降锁命令设置','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 充电桩返回数据（地锁收到遥控地锁升锁与降锁命令指令，响应本数据）
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function setFloorLockResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['pile_gun_number'] = substr($dataInfo, 14,2);//获取设备枪号
        $data['back_status'] = substr($dataInfo, 16,2);//地锁控制返回标志
        //获取设备信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        $lockWhere = "pile_id='".$pileInfo['id']."' && gun_id=".$gunInfo['id'];
        $lockInfo = $db->select('*')->from('jy_pile_floor_lock')->where($lockWhere)->row();
        $backData = ['code'=>0,'msg'=>'地锁收到遥控地锁升锁与降锁命令指令','back_data'=>''];
        //添加地桩锁记录
        $this->addLockOperationRecord($db,$lockInfo,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 远程重启
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function setPileRestart($pileInfo,$data){
        if($data['restart_status'] == 1){  //立刻更新
            $restartStatus = "01";
        }else{
            $restartStatus = "02";
        }
        $contentData = $pileInfo['device_sn'].$restartStatus;
        $backInfo = $this->setBackData('0011','00','92',$contentData);
        $backData = ['code'=>0,'msg'=>'远程重启','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 远程重启应答
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function setPileRestartResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['restart_status'] = substr($dataInfo, 14,2);//设置结果
        //获取设备信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        if($data['restart_status'] == '01'){
            $backData = ['code'=>0,'msg'=>'远程重启成功','back_data'=>''];
        }else{
            $backData = ['code'=>1,'msg'=>'远程重启失败','back_data'=>''];
        }
        //添加充电桩操作记录
        $this->addOperationRecord($db,$pileInfo,12,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 远程更新
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function pileLongRangeUpdate($pileInfo,$data){
        if($data['device_type'] == 1){  //设备类型，1表示直流，2表示交流
            $deviceType = "01"; //01：直流
        }else{
            $deviceType = "02"; //02：交流
        }
        if($data['update_status'] == 1){    //执行类型，1表示立即执行，2表示空闲执行
            $updateStatus = "01"; //01：立即执行
        }else{
            $updateStatus = "02"; //02：空闲执行
        }
        $contentData = $pileInfo['device_sn'].$deviceType.dechex($pileInfo['power_number']).$data['service_address'].$data['service_port'].$data['account'].$data['password'].$data['update_file'].$updateStatus.dechex($data['download_time']);
        $backInfo = $this->setBackData('0026','00','94',$contentData);
        $backData = ['code'=>0,'msg'=>'远程更新','back_data'=>$backInfo];
        return $backData;
    }

    /**
     * 远程更新答应
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function pileLongRangeUpdateResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['update_status'] = substr($dataInfo, 14,2);//升级状态
        //获取设备信息
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        if($data['update_status'] == '00'){
            $backData = ['code'=>0,'msg'=>'远程更新成功','back_data'=>''];
        }else if($data['update_status'] == '01'){
            $backData = ['code'=>1,'msg'=>'远程更新失败-编号错误','back_data'=>''];
        }else if($data['update_status'] == '02'){
            $backData = ['code'=>2,'msg'=>'远程更新失败-程序与桩型号不符','back_data'=>''];
        }else if($data['update_status'] == '03'){
            $backData = ['code'=>3,'msg'=>'远程更新失败-下载更新文件超时','back_data'=>''];
        }else{
            $backData = ['code'=>4,'msg'=>'远程更新失败-未知错误','back_data'=>''];
        }
        //添加充电桩操作记录
        $this->addOperationRecord($db,$pileInfo,13,$data,$backData,$insertId,$backData['msg']);
        return $backData;
    }

    /**
     * 充电桩主动申请并充充电 (用户通过帐号密码及刷卡在充电桩上操作请求充电，多枪并充时每个枪都需要分别上送此帧。)
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function pileApplyParallelCharge($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['pile_number'] = substr($dataInfo, 0,14);//获取设备编号 桩编号
        $data['pile_gun_number'] = substr($dataInfo, 14,2);//获取设备枪号
        $data['start_mode'] = substr($dataInfo, 16,2);//启动方式 0x01 表示通过刷卡启动充电 0x02 表求通过帐号启动充电（暂不支持）0x03 表示vin码启动充电
        $data['need_password'] = substr($dataInfo, 18,2);//是否需要密码
        $data['pile_card_account'] = substr($dataInfo, 20,16);//账号或者物理卡号
        $data['pile_card_password'] = substr($dataInfo, 36,32);//输入密码
        $data['pile_vin_code'] = substr($dataInfo, 68,34);//VIN 码
        $data['pile_vin_code'] = substr($dataInfo, 102,2);//主辅枪标记 0x00 主枪 0x01辅枪
        $data['and_charge_number'] = substr($dataInfo, 104,12);//并充序号 由桩生成，生成规则：年月日时分秒，多个枪并充时上送并充序号一致，标志为同一次并充操作

        //获取信息
        $orderSn = $this->getOrderNumber();
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        //启动方式查询 01 表示通过刷卡启动充电
        if($data['start_mode'] == '01'){
            $userCard = $db->select('*')->from('jy_user_card')->where("card_number='".$data['pile_card_account']."' && is_delete=1")->row();
            //没有对应的卡
            $backData = [];
            if(!$userCard){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>1,'msg'=>'卡号不存在','back_data'=>$backInfo];
                //卡被冻结
            }else if($userCard['status'] == 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'02'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>2,'msg'=>'该卡被冻结','back_data'=>$backInfo];
                //卡中存在未结算记录
            }else{
                //账号余额不足
                if($userCard['user_money'] <= 0){
                    $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'03'.$data['and_charge_number'];
                    $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                    $backData = ['code'=>4,'msg'=>'该卡余额不足','back_data'=>$backInfo];
                }else{
                    $userInfo = $db->select('*')->from('jy_user')->where("id=".$userCard['user_id'])->row();
                    //该卡不存在用户
                    if(!$userInfo){
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01'.$data['and_charge_number'];
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>5,'msg'=>'用户不存在','back_data'=>$backInfo];
                    }else{
                        //判断是否存在未结账订单
                        $orderWhere = 'uid='.$userInfo['id']." && is_del= 0 && paid=0 && status < 3 && start_type=1";
                        $orderCheck = $db->select('*')->from('jy_pile_order')->where($orderWhere)->row();
                        if($orderCheck){
                            $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'04'.$data['and_charge_number'];
                            $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                            $backData = ['code'=>3,'msg'=>'该卡存在未结账记录','back_data'=>$backInfo];
                        }else{
                            $otherData = ['start_time'=>date("Y-m-d H:i:s"),'battery_type'=>'FFH','start_type'=>1,'gun_id'=>$gunInfo['gun_id']];
                            $cardUpdateData = ['status'=>2,'update_time'=>date("Y-m-d H:i:s")];
                            //$db->beginTrans();
                            //$db->commitTrans();
                            //$db->rollBackTrans();
                            $gunUpdateData = ['is_status'=> 3,'update_time'=>date("Y-m-d H:i:s")];
                            //修改枪的状态
                            $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
                            //添加枪操作记录
                            $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);
                            //添加订单
                            $db->beginTrans();
                            $orderResult = $this->addOrder($db,$orderSn,$pileInfo,$data['pile_gun_number'],$userInfo,$otherData);
                            //修改卡的状态
                            $cardUpdateResult = $db->update('jy_user_card')->where('id='.$userCard['id'])->cols($cardUpdateData)->query();
                            if(isset($orderResult['id']) && $orderResult['id'] > 0 && $cardUpdateResult){
                                $db->commitTrans();
                                //添加订单操作记录
                                $orderRecordResult = $db->insert('jy_order_status')->cols([
                                    'order_id'=>$orderResult['id'],
                                    'user_id'=>$orderResult['uid'],
                                    'type'=>1,
                                    'remark'=>'用户创建订单',
                                    'create_time'=>date("Y-m-d H:i:s"),
                                ])->query();
                                $userMoney = dechex($userCard['user_money'] * 100);
                                $moneyLength = strlen((string)$userMoney);
                                if($moneyLength > 8){
                                    $userMoney = substr($userMoney,0,8);
                                }else if($moneyLength < 8){
                                    $userMoney = str_pad($userMoney,8,0,STR_PAD_LEFT);
                                }
                                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].$userMoney.'01'.'00'.$data['and_charge_number'];
                                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                                $backData = ['code'=>0,'msg'=>'启动充电成功','back_data'=>$backInfo];
                            }else{
                                $db->rollBackTrans();
                                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'0C'.$data['and_charge_number'];
                                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                                $backData = ['code'=>6,'msg'=>'启动充电添加订单失败','back_data'=>$backInfo];
                            }
                        }
                    }
                }
            }
            //添加充电桩操作记录
            $this->addOperationRecord($db,$pileInfo,3,$data,$backData,$insertId,$backData['msg']);
            return $backData;

            //账号登录
        }else if($data['start_mode'] == '02'){
            $userInfo = $db->select('*')->from('jy_user')->where("account=".$data['pile_card_account'])->row();
            //不存在用户
            if(!$userInfo){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>1,'msg'=>'账户不存在','back_data'=>$backInfo];
                //账户被冻结
            }else if($userInfo['status'] == 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'02'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>2,'msg'=>'该账户被冻结','back_data'=>$backInfo];
                //密码不一致
            }else if($data['need_password'] == "01" && $userInfo['pwd'] != $data['pile_card_password']){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'07'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>7,'msg'=>'密码错误','back_data'=>$backInfo];
                //账户余额不足
            }else if($userInfo['now_money'] <= 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'03'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>4,'msg'=>'账户余额不足','back_data'=>$backInfo];
            }else{
                //判断是否存在未结账订单
                $orderWhere = 'uid='.$userInfo['id']." && is_del= 0 && paid=0 && status < 3 && start_type=2";
                $orderCheck = $db->select('*')->from('jy_pile_order')->where($orderWhere)->row();
                if($orderCheck){
                    $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'04'.$data['and_charge_number'];
                    $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                    $backData = ['code'=>3,'msg'=>'该用户在未结账订单','back_data'=>$backInfo];
                }else{
                    $otherData = ['start_time'=>date("Y-m-d H:i:s"),'battery_type'=>'FFH','start_type'=>2,'gun_id'=>$gunInfo['gun_id']];
                    //$db->beginTrans();
                    //$db->commitTrans();
                    //$db->rollBackTrans();
                    $orderResult = $this->addOrder($db,$orderSn,$pileInfo,$data['pile_gun_number'],$userInfo,$otherData);
                    $gunUpdateData = ['is_status'=> 3,'update_time'=>date("Y-m-d H:i:s")];
                    $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
                    //添加枪操作记录
                    $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);
                    if(isset($orderResult['id']) && $orderResult['id'] > 0){
                        //添加订单操作记录
                        $orderRecordResult = $db->insert('jy_order_status')->cols([
                            'order_id'=>$orderResult['id'],
                            'user_id'=>$orderResult['uid'],
                            'type'=>1,
                            'remark'=>'用户创建订单',
                            'create_time'=>date("Y-m-d H:i:s"),
                        ])->query();
                        $userMoney = dechex($userInfo['now_money'] * 100);
                        $moneyLength = strlen((string)$userMoney);
                        if($moneyLength > 8){
                            $userMoney = substr($userMoney,0,8);
                        }else if($moneyLength < 8){
                            $userMoney = str_pad($userMoney,8,0,STR_PAD_LEFT);
                        }
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].$userMoney.'01'.'00'.$data['and_charge_number'];
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>0,'msg'=>'启动充电成功','back_data'=>$backInfo];
                    }else{
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'0C'.$data['and_charge_number'];
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>1,'msg'=>'启动充电添加订单失败','back_data'=>$backInfo];
                    }
                }
            }
            //添加充电桩操作记录
            $this->addOperationRecord($db,$pileInfo,3,$data,$backData,$insertId,$backData['msg']);
            return $backData;
            //vin码登录
        }else if($data['start_mode'] == '03'){
            $userInfo = $db->select('*')->from('jy_user')->where("vin_number=".$data['pile_vin_code'])->row();
            //不存在用户
            if(!$userInfo){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>1,'msg'=>'账户不存在','back_data'=>$backInfo];
                //账户被冻结
            }else if($userInfo['status'] == 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'02'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>2,'msg'=>'该账户被冻结','back_data'=>$backInfo];
                //密码不一致
            }else if($data['need_password'] == "01" && $userInfo['pwd'] != $data['pile_card_password']){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'07'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>7,'msg'=>'密码错误','back_data'=>$backInfo];
                //账户余额不足
            }else if($userInfo['now_money'] <= 0){
                $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'03'.$data['and_charge_number'];
                $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                $backData = ['code'=>4,'msg'=>'账户余额不足','back_data'=>$backInfo];
            }else{
                //判断是否存在为结账订单
                $orderWhere = 'uid='.$userInfo['id']." && is_del= 0 && paid=0 && status < 3 && start_type=3";
                $orderCheck = $db->select('*')->from('jy_pile_order')->where($orderWhere)->row();
                if($orderCheck){
                    $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'04'.$data['and_charge_number'];
                    $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                    $backData = ['code'=>3,'msg'=>'该用户在未结账订单','back_data'=>$backInfo];
                }else{
                    $otherData = ['start_time'=>date("Y-m-d H:i:s"),'battery_type'=>'FFH','start_type'=>3,'gun_id'=>$gunInfo['gun_id']];
                    //$db->beginTrans();
                    //$db->commitTrans();
                    //$db->rollBackTrans();
                    $orderResult = $this->addOrder($db,$orderSn,$pileInfo,$data['pile_gun_number'],$userInfo,$otherData);
                    $gunUpdateData = ['is_status'=> 3,'update_time'=>date("Y-m-d H:i:s")];
                    $gunUpdateResult = $db->update('jy_charge_pile_gun')->where('id='.$gunInfo['id'])->cols($gunUpdateData)->query();
                    //添加枪操作记录
                    $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);
                    if(isset($orderResult['id']) && $orderResult['id'] > 0){
                        //添加订单操作记录
                        $orderRecordResult = $db->insert('jy_order_status')->cols([
                            'order_id'=>$orderResult['id'],
                            'user_id'=>$orderResult['uid'],
                            'type'=>1,
                            'remark'=>'用户创建订单',
                            'create_time'=>date("Y-m-d H:i:s"),
                        ])->query();
                        $userMoney = dechex($userInfo['now_money'] * 100);
                        $moneyLength = strlen((string)$userMoney);
                        if($moneyLength > 8){
                            $userMoney = substr($userMoney,0,8);
                        }else if($moneyLength < 8){
                            $userMoney = str_pad($userMoney,8,0,STR_PAD_LEFT);
                        }
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].$userMoney.'01'.'00'.$data['and_charge_number'];
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>0,'msg'=>'启动充电成功','back_data'=>$backInfo];
                    }else{
                        $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'0C'.$data['and_charge_number'];
                        $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
                        $backData = ['code'=>1,'msg'=>'启动充电添加订单失败','back_data'=>$backInfo];
                    }
                }
            }
            //添加充电桩操作记录
            $this->addOperationRecord($db,$pileInfo,3,$data,$backData,$insertId,$backData['msg']);
            return $backData;
        }else{
            $contentData = $orderSn.$data['pile_number'].$data['pile_gun_number'].$data['pile_card_account'].'00000000'.'00'.'01'.$data['and_charge_number'];
            $backInfo = $this->setBackData($parameterData['sor_number'],$parameterData['encryption'],'32',$contentData);
            return ['code'=>1,'msg'=>'启动方式不存在','back_data'=>$backInfo];
        }
    }

    /**
     * 运营平台远程控制并充启机
     * @param $db
     * @param $userInfo
     * @param $pileInfo
     * @param $data
     * @return array
     */
    function pileParallelCharge($db,$userInfo,$pileInfo,$data){
        $userCard = $db->select('*')->from('jy_user_card')->where("user_id='".$userInfo['id']."' && is_delete=1")->row();
        $userMoney = dechex($userInfo['now_money'] * 100);
        $moneyLength = strlen((string)$userMoney);
        if($moneyLength > 8){
            $userMoney = substr($userMoney,0,8);
        }else if($moneyLength < 8){
            $userMoney = str_pad($userMoney,8,0,STR_PAD_LEFT);
        }
        $contentData = $data['order_info']['order_sn'].$pileInfo['device_sn'].$data['pile_gun']['num'].$data['user_card']['logical_card'].$data['user_card']['card_number'].$userMoney.(date("YmdHis"));
        $backInfo = $this->setBackData('007C','00','34',$contentData);
        $backData = ['code'=>0,'msg'=>'运营平台远程控制并充启机','back_data'=>$backInfo];
        return $backData;
    }


    /**
     * 远程启机命令回复
     * @param $db
     * @param $parameterData
     * @param $insertId
     * @return array
     */
    function pileParallelChargeResponse($db,$parameterData,$insertId){
        $dataInfo = $parameterData['data_info'];
        $data = [];
        $data['order_sn'] = substr($dataInfo, 0,32);//获取订单编号 交易流水号
        $data['pile_number'] = substr($dataInfo, 32,14);//获取设备编号 桩编号
        $data['pile_gun_number'] = substr($dataInfo, 46,2);//获取设备枪号
        $data['start_result'] = substr($dataInfo, 48,2);//设备启动结果 0x00失败 0x01成功
        $data['start_error'] = substr($dataInfo, 48,2);//失败原因
        $data['main_or_auxiliary_gun'] = substr($dataInfo, 50,2);//主辅枪标记 0x00 主枪 0x01辅枪
        $data['and_charge_number'] = substr($dataInfo, 52,12);//并充序号 下发的并充序号
        $orderInfo = $db->select('*')->from('jy_pile_order')->where("order_sn=".$data['order_sn'])->row();
        $pileInfo = $db->select('*')->from('jy_charge_pile')->where("device_sn='".$data['pile_number']."' && is_delete=1")->row();
        $gunInfo = $db->select('*')->from('jy_charge_pile_gun')->where("pile_id='".$pileInfo['id']."' && num=".$data['pile_gun_number'])->row();
        //启动成功
        if($data['start_result'] == '01'){
            //启动充电桩充电
            if($orderInfo['status'] != 1){
                $orderData = [
                    'status'=>1,
                    'update_time'=>date("Y-m-d H:i:s"),
                    'charge_hand_content'=>json_encode($data,JSON_UNESCAPED_UNICODE),
                ];
                if($orderInfo['start_time'] == '') $orderData['start_time'] = date("Y-m-d H:i:s");
                $orderResult = $db->update('jy_pile_order')->cols($orderData)->where('id='.$orderInfo['id'])->query();
                $orderRecordResult = $db->insert('jy_order_status')->cols([
                    'order_id'=>$orderInfo['id'],
                    'user_id'=>$orderInfo['uid'],
                    'type'=>2,
                    'remark'=>'充电桩启动充电，修改订单为充电状态',
                    'create_time'=>date("Y-m-d H:i:s"),
                ])->query();
            }
            if($gunInfo['is_status'] != 3 || $gunInfo['error_remark'] != ''){
                $gunData = ['is_status'=>3,'error_remark'=>'','update_time'=>date("Y-m-d H:i:s")];
                $gunResult = $db->update('jy_charge_pile_gun')->cols($gunData)->where('id='.$gunInfo['id'])->query();
                $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'修改枪状态成功'],$insertId);;
            }
            $backData = ['code'=>0,'msg'=>'充电启动成功','back_data'=>''];
        }else if($data['start_result'] == '00'){
            //启动充电桩充电
            if($orderInfo['status'] == 1){
                $orderData = [
                    'status'=>0,
                    'update_time'=>date("Y-m-d H:i:s"),
                    'charge_hand_content'=>json_encode($data,JSON_UNESCAPED_UNICODE),
                ];
                $orderResult = $db->update('jy_pile_order')->cols($orderData)->where('id='.$orderInfo['id'])->query();
                $orderRecordResult = $db->insert('jy_order_status')->cols([
                    'order_id'=>$orderInfo['id'],
                    'user_id'=>$orderInfo['uid'],
                    'type'=>2,
                    'remark'=>'充电桩启动充电失败，修改订单为待充电状态',
                    'create_time'=>date("Y-m-d H:i:s"),
                    'content_info'=>json_encode($data,JSON_UNESCAPED_UNICODE),
                ])->query();
            }
            if($gunInfo['is_status'] == 3 || $gunInfo['error_remark'] == ''){
                $gunData = ['is_status'=>1,'error_remark'=>'充电启动失败','update_time'=>date("Y-m-d H:i:s")];
                $gunResult = $db->update('jy_charge_pile_gun')->cols($gunData)->where('id='.$gunInfo['id'])->query();
                $this->addGunOperationRecord($db,$pileInfo,$gunInfo,8,$data,['code'=>0,'msg'=>'启动充电失败，修改枪为空闲状态'],$insertId);;
            }
            $backData = ['code'=>1,'msg'=>'充电启动失败','back_data'=>''];
        }else{
            $backData = ['code'=>2,'msg'=>'启动参数有误','back_data'=>''];
        }
        return $backData;

    }

    /**
     * bin转10进制
     * @param $str 16进制的字符串
     * @param $number  通讯的长度
     * @param $ratio    小数比例
     * @return float|int
     */
    function binToDecimal($str,$number,$ratio = 1){
        //dump($str);
        $backStr = '';
        for($i=0;$i<$number;$i++){
            $start = $i * 2;
            $getStr = substr($str,$start,2);
            $backStr = $getStr . $backStr;
        }
        //dump($backStr);
        $setNumber = hexdec($backStr) * $ratio;
        return $setNumber;
    }

    /**
     * 10进制转为16进制进行通讯
     * @param $number
     * @param $length
     * @return string
     */
    function numberToBin($number,$length){
        $getHex = dechex($number);
        $getLength = strlen((string)$getHex);
        if($getLength > $length){
            $getHex = substr($getHex,0,$length);
        }else if($getLength < $length){
            $getHex = str_pad($getHex,$length,0,STR_PAD_LEFT);
        }
        $setLength = $length / 2;
        $backStr = '';
        for($i = 0;$i<$setLength;$i++){
            $start = $i * 2;
            $getData = substr($getHex,$start,2);
            $backStr = $getData.$backStr;
        }
        return strtoupper($backStr);
    }

    /**
     * CP56Time时间格式转为标准时间格式
     * @param $timeData
     * @return string
     */
    function cP56TimeToFormatTime($timeData){
        //获取秒 98B70E11100314（当前时间：2020-03-16 17:14:47）
        $second1 = substr($timeData, 2,2);//获取秒
        $second2 = substr($timeData, 0,2);//获取秒
        $secondTime = ceil(hexdec($second1.$second2)/1000);//秒
        $minTime = hexdec(substr($timeData, 4,2));//分
        $hourTime = hexdec(substr($timeData, 6,2));//时
        $dayTime = hexdec(substr($timeData, 8,2));//日
        $monthTime = hexdec(substr($timeData, 10,2));//月
        $yearTime = '20'.hexdec(substr($timeData, 12,2));//年
        if(strlen($secondTime) == 1) $secondTime = '0'.$secondTime;
        if(strlen($minTime) == 1) $minTime = '0'.$minTime;
        if(strlen($hourTime) == 1) $hourTime = '0'.$hourTime;
        if(strlen($dayTime) == 1) $dayTime = '0'.$dayTime;
        if(strlen($monthTime) == 1) $monthTime = '0'.$monthTime;
        if(strlen($yearTime) == 1) $yearTime = '0'.$yearTime;
        $backTime = $yearTime."-".$monthTime."-".$dayTime." ".$hourTime.":".$minTime.":".$secondTime;
        return $backTime;
    }

    /**
     * 格式时间转换为CP56Time时间
     * @param $timeData
     * @return string
     */
    function formatTimeToCP56Time($timeData){
        $getTime = strtotime($timeData);
        $getSecond = dechex(date("s",$getTime)*1000);
        $second1 = substr($getSecond, 0,2);//获取秒
        $second2 = substr($getSecond, 2,2);//获取秒
        if(strlen($second1) == 1) $second1 = '0'.$second1;
        if(strlen($second1) == 0){
            $second2 = '00';
        }else if(strlen($second1) == 1){
            $second2 = '0'.$second2;
        }
        $second = $second2.$second1;
        $min = dechex(date("i",$getTime));
        $hous = dechex(date("H",$getTime));
        $day = dechex(date("d",$getTime));
        $month = dechex(date("m",$getTime));
        $year = dechex(substr(date("Y",$getTime),2,2));
        if(strlen($min) == 1) $min = '0'.$min;
        if(strlen($hous) == 1) $hous = '0'.$hous;
        if(strlen($day) == 1) $day = '0'.$day;
        if(strlen($month) == 1) $month = '0'.$month;
        return strtoupper($second.$min.$hous.$day.$month.$year);
    }

    /**
     * 记录上传上来的数据
     * @param $db
     * @param $client_id
     * @param $message
     * @param $title
     * @param $codeType
     * @param string $remark
     * @return mixed
     */
    function addSendRecord($db,$clientInfo,$title,$message,$codeType,$remark=''){
        return $db->insert("jy_workerman_send")->cols([
            'title'=>$title,
            'pile_id'=>$clientInfo['pile_id'],
            'client_id'=>$clientInfo['client_id'],
            'content'=>$message,
            'code_type'=>$codeType,
            'remark'=>$remark,
            'create_time'=>date("Y-m-d H:i:s"),
            'update_time'=>date("Y-m-d H:i:s"),
        ])->query();
    }




}
